using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

namespace org.jawk.backend
{
    /// <summary>The reference implementation of the Jawk compiler.</summary>
    /// <remarks>
    /// The reference implementation of the Jawk compiler.
    /// Jawk intermediate code is analyzed and converted to
    /// appropriate Java bytecode for execution on a modern
    /// JVM.
    /// <a href="http://jakarta.apache.org/bcel/" target=_TOP>The Apache Byte Code Engineering Library (BCEL)</a>
    /// is used to manage the construction
    /// of the compiled bytecode.
    /// <p>
    /// Since this reference implementation relies on the
    /// BCEL to execute, Jawk employs reflection to
    /// classload this compiler implementation.  If the
    /// reflection fails, it is most likely because
    /// the BCEL library cannot be found in the classpath.
    /// Reflection was used to ensure that Jawk will
    /// build and execute, even without the presence of
    /// the BCEL.
    /// <p>
    /// The architecture of the resultant class is nearly
    /// identical to the following Java code
    /// (assuming AwkScript as the classname and no package
    /// name is provided via the -d argument):
    /// <blockquote>
    /// <pre>
    /// import org.jawk.jrt.*;
    /// import org.jawk.util.AwkParameters;
    /// import java.util.*;
    /// import java.util.regex.*;
    /// import java.io.*;
    /// public class AwkScript implements VariableManager {
    /// <strong>// use this field as the third argument to the AwkParameters
    /// // constructor when executing ScriptMain directly</strong>
    /// public static final String EXTENSION_DESCRIPTION = <i><strong>extension-description-string</strong></i>;
    /// private static final Integer ZERO = new Integer(0);
    /// private static final Integer ONE = new Integer(1);
    /// private static final Integer MINUS_ONE = new Integer(-1);
    /// public static void main(String args[]) {
    /// AwkScript as = new AwkScript();
    /// // this is why org.jawk.util.AwkParameters is in jrt.jar ...
    /// AwkParameters ap = new AwkParameters(AwkScript.class, args, EXTENSION_DESCRIPTION);
    /// // to send the error code back to the calling process
    /// System.exit(as.ScriptMain(ap));
    /// }
    /// <strong>// to satisfy the VariableManager interface
    /// // Note: field names here correspond to a global_N field
    /// // which are assigned upon compilation of the script.</strong>
    /// public final Object getARGC() { if (<i><strong>argc_field</strong></i> == null) return ""; else return <i><strong>argc_field</strong></i>; }
    /// public final Object getCONVFMT() { if (<i><strong>convfmt_field</strong></i> == null) return ""; else return <i><strong>convfmt_field</strong></i>; }
    /// public final Object getFS() { if (<i><strong>fs_field</strong></i> == null) return ""; else return <i><strong>fs_field</strong></i>; }
    /// public final Object getARGV() { return <i><strong>argv_field</strong></i>; }
    /// public final Object getOFS() { if (<i><strong>ofs_field</strong></i> == null) return ""; else return <i><strong>ofs_field</strong></i>; }
    /// public final Object getRS() { if (<i><strong>rs_field</strong></i> == null) return ""; else return <i><strong>rs_field</strong></i>; }
    /// public final void setFILENAME(String arg) { <i><strong>filename_field</strong></i> = arg; }
    /// public final void setNF(String arg) { <i><strong>nf_field</strong></i> = arg; }
    /// private final Object getNR() { if (<i><strong>nr_field</strong></i> == null) return ""; else return <i><strong>nr_field</strong></i>; }
    /// private final Object getFNR() { if (<i><strong>fnr_field</strong></i> == null) return ""; else return <i><strong>fnr_field</strong></i>; }
    /// public final void incNR() { <i><strong>nr_field</strong></i> = (int) JRT.toDouble(JRT.inc(getNR())); }
    /// public final void incFNR() { <i><strong>fnr_field</strong></i> = (int) JRT.toDouble(JRT.inc(getFNR())); }
    /// public final void resetFNR() { <i><strong>fnr_field</strong></i> = ZERO; }
    /// public final void assignField(String name, Object value) {
    /// if (name.equals("<i><strong>scalar1</strong></i>")) <i><strong>scalar1_field</strong></i> = value;
    /// else if (name.equals("<i><strong>scalar2</strong></i>")) <i><strong>scalar2_field</strong></i> = value;
    /// else if (name.equals("<i><strong>scalar3</strong></i>")) <i><strong>scalar3_field</strong></i> = value;
    /// ...
    /// else if (name.equals("<i><strong>scalarN</strong></i>")) <i><strong>scalarN_field</strong></i> = value;
    /// else if (name.equals("<i><strong>funcName1</strong></i>")) <i>throw an exception</i>;
    /// else if (name.equals("<i><strong>funcName2</strong></i>")) <i>throw an exception</i>;
    /// ...
    /// else if (name.equals("<i><strong>funcNameX</strong></i>")) <i>throw an exception</i>;
    /// else if (name.equals("<i><strong>assocArrayName1</strong></i>")) <i>throw an exception</i>;
    /// else if (name.equals("<i><strong>assocArrayName2</strong></i>")) <i>throw an exception</i>;
    /// ...
    /// else if (name.equals("<i><strong>assocArrayNameM</strong></i>")) <i>throw an exception</i>;
    /// }
    /// private JRT input_runtime;
    /// private HashMap regexps;
    /// private HashMap pattern_pairs;
    /// private int exit_code;
    /// private int oldseed;
    /// private Random random_number_generator;
    /// <strong>// global_N refers to all the global variables,
    /// // those which are defined by default
    /// // (i.e., ARGC, ARGV, ENVIRON, NF, etc.)
    /// // and vars declared by the script.
    /// // The _SET_NUM_GLOBALS_ opcode allocates
    /// // these fields.</strong>
    /// private Object global_0;
    /// private Object global_1;
    /// private Object global_2;
    /// ...
    /// private Object global_N;
    /// <strong>// Call this method to invoke the Jawk script.
    /// // Refer to the static main method implementation
    /// // and Javadocs on how to build the AwkParameters.
    /// // Use the public static String EXTENSION_DESCRIPTION
    /// // field (within AwkScript) as the third parameter
    /// // to the AwkParameters constructor to ensure proper
    /// // extension description in the usage statement.</strong>
    /// public final int ScriptMain(AwkParameters awk_parameters) {
    /// // local variables
    /// double dregister;
    /// StringBuffer sb = new StringBuffer();
    /// // Field Allocation
    /// // ----------------
    /// // Could have be done in the class constructor,
    /// // but placed here to ensure proper repeat initialization
    /// // if repeat execution is required
    /// // within the same JVM instance.  Because
    /// // if these were within the class constructor, each of these
    /// // data structures / int values would have to be
    /// // reinitialized in some way anyway.
    /// input_runtime = JRT(this);	// this = VariableManager
    /// regexps = new HashMap();
    /// pattern_pairs = new HashMap();
    /// oldseed = 0;
    /// random_number_generator = new Random(null);
    /// exit_code = 0;
    /// // script execution
    /// try {
    /// ///
    /// /// Compiled BEGIN and input rule blocks code here.
    /// /// (EndException is thrown when exit() is encountered.)
    /// ///
    /// } catch (EndException ee) {
    /// // do nothing
    /// }
    /// try {
    /// runEndBlocks();
    /// } catch (EndException ee) {
    /// // do nothing
    /// }
    /// return exit_code;
    /// }
    /// public void runEndBlocks() {
    /// double dregister;
    /// StringBuffer sb = new StringBuffer();
    /// ///
    /// /// Compiled END blocks code here.
    /// /// (EndException is thrown when exit() is encountered.)
    /// ///
    /// }
    /// <strong>// One of these exists for every function definition.
    /// // Arguments are reversed from its Jawk source.</strong>
    /// public Object FUNC_<i><strong>function_name</strong></i>(Object oN, Object oN-1, ... Object o2, Object o1) {
    /// Object _return_value_ = null;
    /// StringBuffer sb = new StringBuffer();
    /// double dregister = 0.0;
    /// ///
    /// /// Compiled function <i><strong>function_name</strong></i> code here.
    /// /// (A return() sets the _return_value_ and falls out of this
    /// ///  function code block.)
    /// /// (EndException is thrown when exit() is encountered.)
    /// ///
    /// return _return_value_;
    /// }
    /// <strong>// The following is created for every optarg version of the function
    /// // call that exists within the script for this function_name.
    /// // X &gt; 0 && N &gt; X</strong>
    /// public final Object FUNC_<i><strong>function_name</strong></i>(Object oX, Object oX-1, ... Object o2, Object o1) {
    /// return FUNC_<i><strong>function_name</strong></i>(null, null, ..., null, oX, oX-1, ..., o2, o1);
    /// }
    /// }
    /// </pre>
    /// </blockquote>
    /// </remarks>
    /// <seealso cref="IAwkCompiler">IAwkCompiler</seealso>
    /// <seealso cref="AVM">AVM</seealso>
    /// <seealso cref="org.jawk.jrt.IVariableManager">org.jawk.jrt.IVariableManager</seealso>
    /// <author>Danny Daglas</author>
    public class AwkCompilerImpl : org.jawk.backend.IAwkCompiler
    {
        private static readonly bool VERBOSE = false;

        private static readonly System.Type AssocArrayClass = typeof (org.jawk.jrt.AssocArray
            );

        private static readonly System.Type PatternPairClass = typeof (org.jawk.jrt.PatternPair
            );

        private static readonly System.Type KeyListImplClass = typeof (org.jawk.jrt.KeyListImpl
            );

        private static readonly System.Type EndExceptionClass = typeof (org.jawk.jrt.EndException
            );

        private static readonly System.Type AwkRuntimeExceptionClass = typeof (org.jawk.jrt.AwkRuntimeException
            );

        private static readonly System.Type VariableManagerClass = typeof (org.jawk.jrt.IVariableManager
            );

        private static readonly System.Type JRT_Class = typeof (org.jawk.jrt.JRT);

        static AwkCompilerImpl()
        {
            VERBOSE = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["jawk.verbose"]);
        }

        // These classes should exist in the jrt package because
        // the jrt.jar file contains the jrt package.
        //assert assertStaticClassVarsAreFromPackage();
        private static bool AssertStaticClassVarsAreFromPackage()
        {
            //String packagename = System.getProperty("jawk.rtPackgeName", "org.jawk.jrt");
            string packagename = "org.jawk.jrt";
            if (packagename != null)
            {
                // use reflection to get all static Class definitions
                // and verify that they are members of the
                // runtime package
                System.Type c = typeof (org.jawk.backend.AwkCompilerImpl);
                // foreach field in declared in the class...
                foreach (System.Reflection.FieldInfo f in c.GetFields())
                {
                    // if a "private static final" member...
                    if (true && f.IsPrivate && f.IsStatic && f.IsInitOnly && f.FieldType == typeof (System.Type))
                    {
                        try
                        {
                            // obtain the value of the field
                            // and apply it here!
                            object o = f.GetValue(null);
                            System.Type cls = (System.Type) o;

                            if (cls.Namespace != packagename)
                            {
                                throw new Exception("Error: " + c + " is not contained within '" +
                                                    packagename + "' package.  Field = " + f);
                            }
                        }
                        catch (System.MemberAccessException iae)
                        {
                            Console.Error.WriteLine(iae);
                            throw new Exception("Caught: " + iae);
                        }
                    }
                }
            }
            // all's well
            return true;
        }

        private string classname;

        private org.apache.bcel.generic.ClassGen cg;

        private org.apache.bcel.generic.InstructionFactory factory;

        private org.apache.bcel.generic.ConstantPoolGen cp;

        private org.jawk.backend.AwkCompilerImpl.MyInstructionList il_main;

        private org.apache.bcel.generic.MethodGen mg_main;

        private System.Collections.Generic.IDictionary<string, int> lv_main = new System.Collections.Generic.Dictionary
            <string, int>();

        private org.jawk.backend.AwkCompilerImpl.MyInstructionList il_reb;

        private org.apache.bcel.generic.MethodGen mg_reb;

        private System.Collections.Generic.IDictionary<string, int> lv_reb;

        private org.jawk.backend.AwkCompilerImpl.MyInstructionList il;

        private org.apache.bcel.generic.MethodGen mg;

        private System.Collections.Generic.IDictionary<string, int> local_vars;

        private org.apache.bcel.generic.MethodGen mg_temp = null;

        private org.jawk.backend.AwkCompilerImpl.MyInstructionList il_temp = null;

        private System.Collections.Generic.IDictionary<org.jawk.intermediate.IAddress, System.Collections.Generic.IList
            <org.apache.bcel.generic.BranchHandle>> bhs_temp = null;

        private System.Collections.Generic.IDictionary<int, org.apache.bcel.generic.InstructionHandle
            > ihs_temp = null;

        private System.Collections.Generic.IDictionary<string, int> lvs_temp = null;

        private org.jawk.util.AwkParameters parameters;

        /// <summary>Creates the compiler implementation.</summary>
        /// <remarks>
        /// Creates the compiler implementation.
        /// Jawk invokes this via reflection.
        /// </remarks>
        /// <param name="parameters">Parameters to the script compiler.</param>
        /// <seealso cref="org.jawk.Awk">org.jawk.Awk</seealso>
        public AwkCompilerImpl(org.jawk.util.AwkParameters parameters)
        {
            // reb = runEndBlocks
            // reb = runEndBlocks
            // reb = runEndBlocks
            // active instructionlist
            // active methodgen
            // active localvars
            this.parameters = parameters;
        }

        /// <summary>
        /// Overrides BCEL's InstructionList to provide instruction marking
        /// services.
        /// </summary>
        /// <remarks>
        /// Overrides BCEL's InstructionList to provide instruction marking
        /// services.
        /// <p>
        /// Instruction marking aids in retrieving the first instruction
        /// of a group of instructions that represents one Jawk opcode.
        /// <p>
        /// A mark must occur prior to appending an instruction
        /// to the instruction list.  Then, the marked instruction
        /// must be retrieved before another instruction is marked.
        /// In other words, the instruction list keeps state of
        /// the most recent marked instruction.  The application
        /// code must retrieve the marked instruction as soon
        /// as possible to do it's Jawk opcode to JVm instruction
        /// management.
        /// </remarks>
        [System.Serializable]
        private sealed class MyInstructionList : org.apache.bcel.generic.InstructionList
        {
            private org.apache.bcel.generic.InstructionHandle marked_handle = null;

            private bool marked = false;

            public void Mark()
            {
                marked = true;
            }

            public override org.apache.bcel.generic.InstructionHandle Append(org.apache.bcel.generic.Instruction i)
            {
                org.apache.bcel.generic.InstructionHandle retval = base.Append(i);
                if (marked)
                {
                    marked_handle = retval;
                    marked = false;
                }
                return retval;
            }

            public override org.apache.bcel.generic.BranchHandle Append(org.apache.bcel.generic.BranchInstruction
                                                                            i)
            {
                org.apache.bcel.generic.BranchHandle retval = base.Append(i);
                if (marked)
                {
                    marked_handle = retval;
                    marked = false;
                }
                return retval;
            }

            public override org.apache.bcel.generic.InstructionHandle Append(
                org.apache.bcel.generic.ICompoundInstruction
                    i)
            {
                org.apache.bcel.generic.InstructionHandle retval = base.Append(i);
                if (marked)
                {
                    marked_handle = retval;
                    marked = false;
                }
                return retval;
            }

            public org.apache.bcel.generic.InstructionHandle MarkedHandle()
            {
                org.apache.bcel.generic.InstructionHandle ih = marked_handle;
                marked_handle = null;
                return ih;
            }
        }

        /// <summary>
        /// Checks whether a classname is a valid classname
        /// (validity for Jawk, not necessarily for the JVM).
        /// </summary>
        /// <remarks>
        /// Checks whether a classname is a valid classname
        /// (validity for Jawk, not necessarily for the JVM).
        /// Validity is defined as:
        /// <ul>
        /// <li>classname is a non-null, non-empty string
        /// <li>A <strong>classname unit</strong> is defined
        /// as text between the start-of-string and a period,
        /// a period and the end-of-string, or between
        /// two periods.  classname units must be non-empty strings.
        /// <li>classname units must adhere to Java identifier rules.
        /// See java.lang.Character.isJavaIdentifierStart
        /// and java.lang.Character.isJavaIdentifierPart for rules
        /// relating to Java identifiers.
        /// <li>classname must not contain dollar signs ($).
        /// Even though dollar signs are common within class names
        /// to indicate inner classes, the Jawk compiler cannot
        /// process these types of names.
        /// </ul>
        /// <p>
        /// If all of these tests pass, nothing occurs and the
        /// method exits.  Otherwise, an IllegalArgumentException
        /// is thrown
        /// </remarks>
        /// <param name="classname">The classname to verify.</param>
        /// <exception cref="System.ArgumentException">
        /// if the classname does
        /// not conform to the rules described above.
        /// </exception>
        private static void ValidateClassname(string classname)
        {
            // - check for non-null
            //assert classname != null;
            // - check for non-blank classname
            if (classname.Length == 0)
            {
                throw new System.ArgumentException("classname cannot be black");
            }
            // - check for a valid java identifier
            if (classname[0] != '.' && !java.util.Character.IsJavaIdentifierStart(classname[0]))
            {
                throw new System.ArgumentException("classname is not a valid java identifier");
            }
            for (int i = 1; i < classname.Length; i++)
            {
                if (classname[i] != '.' && !java.util.Character.IsJavaIdentifierPart(classname[i]))
                {
                    throw new System.ArgumentException("classname is not a valid java identifier");
                }
            }
            // - check for $
            if (classname.IndexOf("$") >= 0)
            {
                throw new System.ArgumentException("classname cannot contain a $");
            }
            // - check for no ..'s in classname
            if (classname.IndexOf("..") >= 0)
            {
                throw new System.ArgumentException("null-package (..) found in classname");
            }
        }

        // otherwise, all is good
        /// <summary>Retrieves the dirname, if any, from a given classname.</summary>
        /// <remarks>
        /// Retrieves the dirname, if any, from a given classname.
        /// It uses the separator parameter as class "path" separators.
        /// If no separators exist, null is returned.
        /// </remarks>
        /// <param name="classname">The classname to analyze.</param>
        /// <param name="separator">
        /// The separator denoting components
        /// of the class "path".
        /// </param>
        /// <returns>
        /// The "dir" part of the class "path".  If no
        /// separators exist, null is returned.
        /// </returns>
        private static string ExtractDirname(string classname, string separator)
        {
            // converts
            // a.b.c.d
            // to
            // a.b.c
            // (if no periods exist, return null)
            //assert classname != null && classname.length() > 0;
            int dot_idx = classname.LastIndexOf(separator);
            if (dot_idx == -1)
            {
                return null;
            }
            else
            {
                string dirname = classname.Substring(0, dot_idx);
                // convert all "."'s to File.separator's

                return dirname.Replace(separator, System.IO.Path.PathSeparator.ToString());
            }
        }

        /// <summary>
        /// Retrieves the name portion of the class "path" contained
        /// within classname.
        /// </summary>
        /// <remarks>
        /// Retrieves the name portion of the class "path" contained
        /// within classname.
        /// If no separators (periods) exist, classname is returned.
        /// </remarks>
        /// <param name="classname">The classname to analyze.</param>
        /// <returns>
        /// The "name" part of the class "path".  If no
        /// separators (periods) exist, classname is returned.
        /// </returns>
        private static string ExtractClassname(string classname)
        {
            // converts
            // a.b.c.d
            // to
            // d
            //assert classname != null && classname.length() > 0;
            int dot_idx = classname.LastIndexOf(".");
            if (dot_idx == -1)
            {
                return classname;
            }
            else
            {
                return classname.Substring(dot_idx + 1);
            }
        }

        /// <summary>Prepares for compilation.</summary>
        /// <remarks>
        /// Prepares for compilation.
        /// Actions are as follows:
        /// <ul>
        /// <li>Allocate the ScriptMain and runEndBlocks method objects.
        /// <li>Allocate local variables (dregister and sb) for both methods.
        /// <li>Allocate static helper objects (i.e., ZERO, ONE, and MINUS_ONE).
        /// <li>Allocate some global helper objects (i.e., random_seed_generator).
        /// </ul>
        /// <p>
        /// <strong>TODO:</strong> analyze tuples to check for
        /// <ul>
        /// <li>_CONCAT_ - if not found, no need to allocate sb
        /// <li>_RANDOM_ - if not found, no need to allocate random_seed_generator
        /// <li>arithmetic opcodes - if not found, no need to allocate dregister
        /// <li><i>etc...</i>
        /// </ul>
        /// </remarks>
        private void Precompile()
        {
            sourceBuilder.Childs.Add(new Assembly("mscorlib",true));

            sourceBuilder.Childs.Add(new Assembly("AwkScript", false, new Version(1,0,1,0)));

            sourceBuilder.Childs.Add(new Module("AwkScript.exe"));

            Namespace nSpace = new Namespace("Awk.Net");
            sourceBuilder.Childs.Add(nSpace);

            awkScript = new Class("AwkScript");
            nSpace.Childs.Add(awkScript);

            awkScript.Childs.Add(new Field<string>("EXTENSION_DESCRIPTION",parameters.ExtensionDescription(),true,true,Visibility.Public));

            awkScript.Childs.Add(new Field<int>("ZERO", 0, true, true));
            awkScript.Childs.Add(new Field<int>("ONE", 1, true, true));
            awkScript.Childs.Add(new Field<int>("MINUS_ONE", -1, true, true));
            awkScript.Childs.Add(new Field<org.jawk.jrt.JRT>("input_runtime", null));
            awkScript.Childs.Add(new Field<System.Collections.IDictionary>("regexps", null));
            awkScript.Childs.Add(new Field<System.Collections.IDictionary>("pattern_pairs", null));
            awkScript.Childs.Add(new Field<int>("exit_code", 0));
            awkScript.Childs.Add(new Field<int>("oldseed", 0));
            awkScript.Childs.Add(new Field<Random>("random_number_generator", null));
            awkScript.Childs.Add(new Field<object>("global_0", null));
            awkScript.Childs.Add(new Field<object>("global_1", null));
            awkScript.Childs.Add(new Field<object>("global_2", null));
            awkScript.Childs.Add(new Field<object>("global_3", null));
            awkScript.Childs.Add(new Field<object>("global_4", null));
            awkScript.Childs.Add(new Field<object>("global_5", null));
            awkScript.Childs.Add(new Field<object>("global_6", null));
            awkScript.Childs.Add(new Field<object>("global_7", null));
            awkScript.Childs.Add(new Field<object>("global_8", null));
            awkScript.Childs.Add(new Field<object>("global_9", null));
            awkScript.Childs.Add(new Field<object>("global_10", null));
            awkScript.Childs.Add(new Field<object>("global_11", null));
            awkScript.Childs.Add(new Field<object>("global_12", null));
            awkScript.Childs.Add(new Field<object>("global_13", null));
            awkScript.Childs.Add(new Field<object>("global_14", null));

            scriptMain = new Method("ScriptMain", typeof(int), new Type[] { typeof(org.jawk.util.AwkParameters) }, Visibility.Public, true, false);
            awkScript.Childs.Add(scriptMain);
            // assign some local variables to ScriptMain
            scriptMain.LocalVariables.Add(new TypedLocalVariable<double>("dregister",0));
            scriptMain.LocalVariables.Add(new TypedLocalVariable<StringBuilder>("sb", new StringBuilder()));
            

            runEndBlocks = new Method("runEndBlocks", typeof(void));
            awkScript.Childs.Add(runEndBlocks);
            runEndBlocks.LocalVariables.Add(new TypedLocalVariable<double>("dregister", 0));
            runEndBlocks.LocalVariables.Add(new TypedLocalVariable<StringBuilder>("sb", new StringBuilder()));

            
           
            //// setup JVM compilation stuff
            ////classname = "AwkScript";
            //classname = parameters.OutputFilename("AwkScript");
            //ValidateClassname(classname);
            //string script_filename = parameters.script_filename;
            //if (script_filename == null)
            //{
            //    script_filename = "<generated>";
            //}
            //cg = new org.apache.bcel.generic.ClassGen(classname, "java.lang.Object", script_filename
            //    , ACC_PUBLIC | ACC_SUPER, new string[] { VariableManagerClass.FullName });
            //factory = new org.apache.bcel.generic.InstructionFactory(cg);
            //cp = cg.GetConstantPool();
            //il_main = new org.jawk.backend.AwkCompilerImpl.MyInstructionList();
            //mg_main = new org.apache.bcel.generic.MethodGen(ACC_PUBLIC | ACC_FINAL, org.apache.bcel.generic.Type
            //    .INT, new org.apache.bcel.generic.Type[] { GetObjectType(typeof(org.jawk.util.AwkParameters
            //    )) }, new string[] { "parameters" }, "ScriptMain", classname, il_main, cp);
            //// ScriptMain is the main method!
            //il = il_main;
            //mg = mg_main;
            //local_vars = lv_main;
            //il_reb = new org.jawk.backend.AwkCompilerImpl.MyInstructionList();
            //mg_reb = new org.apache.bcel.generic.MethodGen(ACC_PUBLIC, org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] {  }, new string[] {  }, "runEndBlocks", classname, il_reb, cp);
            //// no args
            //lv_reb = new System.Collections.Generic.Dictionary<string, int>();
            //// assign some local variables to runEndBlocks
            //org.apache.bcel.generic.LocalVariableGen dregister_reb = mg_reb.AddLocalVariable("dregister", GetObjectType(typeof(double)), null, null);
            //org.apache.bcel.generic.LocalVariableGen sb_reb = mg_reb.AddLocalVariable("sb", new org.apache.bcel.generic.ObjectType("java.lang.StringBuffer"), null, null);
            //lv_reb["dregister"] = dregister_reb.GetIndex();
            //lv_reb["sb"] = sb_reb.GetIndex();
            //org.apache.bcel.generic.InstructionHandle ih = il_reb.Append(factory.CreateNew("java.lang.StringBuffer"));
            //il_reb.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            //il_reb.Append(factory.CreateInvoke("java.lang.StringBuffer", "<init>", org.apache.bcel.generic.Type.VOID, BuildArgs(new System.Type[] {  }), INVOKESPECIAL));
            //il_reb.Append(factory.CreateStore(new org.apache.bcel.generic.ObjectType("java.lang.StringBuffer"), sb_reb.GetIndex()));
            //dregister_reb.SetStart(ih);
            //sb_reb.SetStart(ih);
            //// assign some local variables to MAIN
            //// for il_main
            //JVMTools_allocateLocalVariable(typeof(double), "dregister");
            //// for CONCAT
            //JVMTools_allocateLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //JVMTools_new("java.lang.StringBuffer");
            //JVMTools_storeToLocalVariable(typeof(System.Text.StringBuilder), "sb");
            ///// STATIC CONSTRUCTOR STUFF
            //org.apache.bcel.generic.InstructionList static_il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen static_mg = new org.apache.bcel.generic.MethodGen
            //    (ACC_STATIC, org.apache.bcel.generic.Type.VOID, org.apache.bcel.generic.Type.NO_ARGS
            //    , new string[] {  }, "<clinit>", classname, static_il, cp);
            //JVMTools_allocateStaticField(typeof(string), "EXTENSION_DESCRIPTION", ACC_PUBLIC);
            //static_il.Append(new org.apache.bcel.generic.PUSH(cp, parameters.ExtensionDescription
            //    ()));
            //static_il.Append(factory.CreateFieldAccess(classname, "EXTENSION_DESCRIPTION", GetObjectType
            //    (typeof(string)), org.apache.bcel.Constants.PUTSTATIC));
            //JVMTools_allocateStaticField(typeof(int), "ZERO");
            //static_il.Append(new org.apache.bcel.generic.PUSH(cp, 0));
            //static_il.Append(factory.CreateInvoke(typeof(int).FullName, "valueOf", GetObjectType
            //    (typeof(int)), BuildArgs(new System.Type[] { typeof(int) }), INVOKESTATIC));
            //static_il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(
            //    int)), org.apache.bcel.Constants.PUTSTATIC));
            //JVMTools_allocateStaticField(typeof(int), "ONE");
            //static_il.Append(new org.apache.bcel.generic.PUSH(cp, 1));
            //static_il.Append(factory.CreateInvoke(typeof(int).FullName, "valueOf", GetObjectType
            //    (typeof(int)), BuildArgs(new System.Type[] { typeof(int) }), INVOKESTATIC));
            //static_il.Append(factory.CreateFieldAccess(classname, "ONE", GetObjectType(typeof(
            //    int)), org.apache.bcel.Constants.PUTSTATIC));
            //JVMTools_allocateStaticField(typeof(int), "MINUS_ONE");
            //static_il.Append(new org.apache.bcel.generic.PUSH(cp, -1));
            //static_il.Append(factory.CreateInvoke(typeof(int).FullName, "valueOf", GetObjectType
            //    (typeof(int)), BuildArgs(new System.Type[] { typeof(int) }), INVOKESTATIC));
            //static_il.Append(factory.CreateFieldAccess(classname, "MINUS_ONE", GetObjectType(
            //    typeof(int)), org.apache.bcel.Constants.PUTSTATIC));
            //static_il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //static_mg.SetMaxStack();
            //static_mg.SetMaxLocals();
            //cg.AddMethod(static_mg.GetMethod());
            //static_il.Dispose();
            //JVMTools_allocateField(JRT_Class, "input_runtime");
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //JVMTools_new(JRT_Class.FullName, VariableManagerClass);
            //JVMTools_storeField(JRT_Class, "input_runtime");
            //JVMTools_allocateField(typeof(System.Collections.IDictionary), "regexps");
            //JVMTools_new("java.util.HashMap");
            //JVMTools_storeField(typeof(System.Collections.IDictionary), "regexps");
            //JVMTools_allocateField(typeof(System.Collections.IDictionary), "pattern_pairs");
            //JVMTools_new("java.util.HashMap");
            //JVMTools_storeField(typeof(System.Collections.IDictionary), "pattern_pairs");
            //// for EXIT
            //JVMTools_allocateField(typeof(int), "exit_code");
            //il.Append(new org.apache.bcel.generic.PUSH(cp, 0));
            //JVMTools_storeField(typeof(int), "exit_code");
            //// for SRAND/RAND
            //JVMTools_allocateField(typeof(int), "oldseed");
            //il.Append(new org.apache.bcel.generic.PUSH(cp, 0));
            //JVMTools_storeField(typeof(int), "oldseed");
            //JVMTools_allocateField(typeof(java.util.Random), "random_number_generator");
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ACONST_NULL);
            //JVMTools_storeField(typeof(java.util.Random), "random_number_generator");
        }

        private StringBuilder cilOutPut;
        private AwkScriptSource sourceBuilder;
        private Class awkScript;
        private Method scriptMain;
        private Method runEndBlocks;

        /// <summary>Entry point to the compiler.</summary>
        /// <remarks>
        /// Entry point to the compiler.
        /// The compiler traverses the AwkTuples produced by
        /// the intermediate step, translating each tuple
        /// into JVM code.  Some post-processing occurs
        /// to resolve branching (jumps to Addresses).
        /// </remarks>
        /// <param name="tuples">
        /// The tuples which are traversed
        /// to produce the compiled result.
        /// </param>
        /// <seealso cref="org.jawk.intermediate.IAddress">org.jawk.intermediate.IAddress</seealso>
        public void Compile(org.jawk.intermediate.AwkTuples tuples)
        {
            cilOutPut = new StringBuilder();
            sourceBuilder = new AwkScriptSource();

            Precompile();

            GetOffsets(tuples);
            org.jawk.intermediate.IPositionForCompilation position =
                (org.jawk.intermediate.IPositionForCompilation) tuples.Top();
            // to keep track of line numbers that have changed
            int previous_lineno = -2;
            while (!position.IsEOF())
            {
                il.Mark();
                int opcode = position.Opcode();
                TranslateToJVM(position, opcode, tuples);
                org.apache.bcel.generic.InstructionHandle ih = il.MarkedHandle();
                if (ih != null)
                {
                    instruction_handles[position.Index()] = ih;
                    // only add line numbers when they have changed ...
                    int lineno = position.LineNumber();
                    if (previous_lineno != lineno)
                    {
                        //mg.AddLineNumber(ih, lineno);
                        previous_lineno = lineno;
                    }
                }
                position.Next();
            }
            //assert mg == mg_reb;
            JVMTools_returnVoid();
            ResolveBranchHandleTargets();
            Postcompile(tuples);
        }

        private void AddExitCode(org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.MethodGen
                                                                                 mg)
        {
            //// strategy:
            ////
            //// try {
            //// 	//code - already contained in InstructionList//
            //// } catch (EndException ee) {}
            //// try {
            //// 	runEndBlocks();
            //// } catch (EndException ee) {}
            //// try1
            //org.apache.bcel.generic.InstructionHandle ih1_start = il.GetStart();
            //org.apache.bcel.generic.InstructionHandle ih1_end = il.GetEnd();
            //org.apache.bcel.generic.BranchHandle bh1 = il.Append(new org.apache.bcel.generic.GOTO
            //    (null));
            //// catch1
            //// (do nothing)
            //org.apache.bcel.generic.InstructionHandle ih1_catch = il.Append(org.apache.bcel.generic.IInstructionConstants
            //    .POP);
            //// try2
            //// run end blocks here!
            //org.apache.bcel.generic.InstructionHandle ih_reb = il.Append(org.apache.bcel.generic.IInstructionConstants
            //    .ALOAD_0);
            //il.Append(factory.CreateInvoke(classname, "runEndBlocks", org.apache.bcel.generic.Type
            //    .VOID, org.apache.bcel.generic.Type.NO_ARGS, org.apache.bcel.Constants.INVOKEVIRTUAL
            //    ));
            //org.apache.bcel.generic.InstructionHandle ih2_end = il.Append(org.apache.bcel.generic.IInstructionConstants
            //    .ALOAD_0);
            //il.Append(factory.CreateFieldAccess(classname, "exit_code", org.apache.bcel.generic.Type
            //    .INT, org.apache.bcel.Constants.GETFIELD));
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.INT));
            //bh1.SetTarget(ih_reb);
            //// catch2
            //// (again, do nothing)
            //org.apache.bcel.generic.InstructionHandle ih2_catch = il.Append(org.apache.bcel.generic.IInstructionConstants
            //    .POP);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(factory.CreateFieldAccess(classname, "exit_code", org.apache.bcel.generic.Type
            //    .INT, org.apache.bcel.Constants.GETFIELD));
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.INT));
            //mg.AddExceptionHandler(ih1_start, ih1_end, ih1_catch, new org.apache.bcel.generic.ObjectType
            //    (EndExceptionClass.FullName));
            //mg.AddExceptionHandler(ih_reb, ih2_end, ih2_catch, new org.apache.bcel.generic.ObjectType
            //    (EndExceptionClass.FullName));
        }

        private void Postcompile(org.jawk.intermediate.AwkTuples tuples)
        {
            //mg_main.SetMaxStack();
            //mg_main.SetMaxLocals();
            //cg.AddMethod(mg_main.GetMethod());
            //il_main.Dispose();
            //mg_reb.SetMaxStack();
            //mg_reb.SetMaxLocals();
            //cg.AddMethod(mg_reb.GetMethod());
            //il_reb.Dispose();
            //try
            //{
            //    cg.AddEmptyConstructor(ACC_PUBLIC);
            //    AddMainMethod();
            //    CreateMethods_VariableManager(tuples);
            //    CreatePartialParamCalls(tuples);
            //    string destdir = parameters.DestDirectory();
            //    string dirname = ExtractDirname(classname, ".");
            //    string clsname = ExtractClassname(classname);
            //    if (dirname != null)
            //    {
            //        clsname = dirname + java.io.File.separator + clsname;
            //    }
            //    if (destdir != null)
            //    {
            //        if (new java.io.File(destdir).Exists())
            //        {
            //            clsname = destdir + java.io.File.separator + clsname;
            //        }
            //        else
            //        {
            //            throw new System.IO.IOException("Directory \"" + destdir + "\" does not exist.");
            //        }
            //    }
            //    string path = ExtractDirname(clsname, java.io.File.separator);
            //    if (path != null)
            //    {
            //        new java.io.File(path).Mkdirs();
            //    }
            //    java.io.FileOutputStream fos = new java.io.FileOutputStream(clsname + ".class");
            //    cg.GetJavaClass().Dump(fos);
            //    if (VERBOSE)
            //    {
            //        System.Console.Error.WriteLine("(wrote: " + cg + ")");
            //    }
            //}
            //catch (System.IO.IOException ioe)
            //{
            //    Console.Error.WriteLine(ioe);
            //    System.Environment.Exit(1);
            //}
        }

        private void AddMainMethod()
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen mg = new org.apache.bcel.generic.MethodGen(ACC_PUBLIC
            //     | ACC_STATIC, org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type
            //    [] { new org.apache.bcel.generic.ArrayType(GetObjectType(typeof(string)), 1) }, 
            //    new string[] { "args" }, "main", classname, il, cp);
            //il.Append(factory.CreateNew(classname));
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            //// ..., mainclass, mainclass, mainclass
            //il.Append(factory.CreateInvoke(classname, "<init>", org.apache.bcel.generic.Type.
            //    VOID, new org.apache.bcel.generic.Type[] {  }, INVOKESPECIAL));
            //// ..., mainclass, mainclass
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            //org.apache.bcel.generic.LocalVariableGen mainclass_arg = mg.AddLocalVariable("mainclass_"
            //    , new org.apache.bcel.generic.ObjectType(classname), null, null);
            //org.apache.bcel.generic.InstructionHandle ih = il.Append(factory.CreateStore(new 
            //    org.apache.bcel.generic.ObjectType(classname), mainclass_arg.GetIndex()));
            //mainclass_arg.SetStart(ih);
            //il.Append(factory.CreateNew(typeof(org.jawk.util.AwkParameters).FullName));
            //// ..., mainclass, mainclass, AwkParameters
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP_X1);
            //// ..., mainclass, AwkParameters, mainclass, AwkParameters
            //il.Append(org.apache.bcel.generic.IInstructionConstants.SWAP);
            //// ..., mainclass, AwkParameters, AwkParameters, mainclass
            //il.Append(factory.CreateInvoke(typeof(object).FullName, "getClass", GetObjectType
            //    (typeof(System.Type)), new org.apache.bcel.generic.Type[] {  }, INVOKEVIRTUAL));
            //// ..., mainclass, AwkParameters, AwkParameters, mainclass.class
            //il.Append(factory.CreateLoad(org.apache.bcel.generic.Type.OBJECT, 0));
            //il.Append(factory.CreateFieldAccess(classname, "EXTENSION_DESCRIPTION", GetObjectType
            //    (typeof(string)), org.apache.bcel.Constants.GETSTATIC));
            //// ..., mainclass, AwkParameters, AwkParameters, mainclass.class, args, desc
            //il.Append(factory.CreateInvoke(typeof(org.jawk.util.AwkParameters).FullName, "<init>"
            //    , org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] { GetObjectType
            //    (typeof(System.Type)), new org.apache.bcel.generic.ArrayType(GetObjectType(typeof(
            //    string)), 1), GetObjectType(typeof(string)) }, INVOKESPECIAL));
            //// ..., mainclass, AwkParameters
            //il.Append(factory.CreateInvoke(classname, "ScriptMain", org.apache.bcel.generic.Type
            //    .INT, new org.apache.bcel.generic.Type[] { GetObjectType(typeof(org.jawk.util.AwkParameters
            //    )) }, INVOKEVIRTUAL));
            //il.Append(factory.CreateInvoke(typeof(Sharpen.Runtime).FullName, "exit", org.apache.bcel.generic.Type
            //    .VOID, new org.apache.bcel.generic.Type[] { org.apache.bcel.generic.Type.INT }, 
            //    INVOKESTATIC));
            //// ??? the return (below) is required, even though we're exit()ing (above) ???
            //// ??? (missing return results in a VerifyError) ???
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //mg.SetMaxStack();
            //mg.SetMaxLocals();
            //cg.AddMethod(mg.GetMethod());
            //il.Dispose();
        }

        private void CreateMethods_VariableManager(org.jawk.intermediate.AwkTuples tuples)
        {
            //CreateGetMethod("getARGC", argc_field);
            //CreateGetMethod("getCONVFMT", convfmt_field);
            //CreateGetMethod("getFS", fs_field);
            //CreateGetMethod(ACC_PRIVATE, "getNR", nr_field);
            //CreateGetMethod(ACC_PRIVATE, "getFNR", fnr_field);
            //CreateMethod_getARGV();
            //CreateGetMethod("getRS", rs_field);
            //CreateGetMethod("getOFS", ofs_field);
            //CreateGetMethod("getSUBSEP", subsep_field);
            //CreateSetMethod("setFILENAME", filename_field, typeof(string));
            //CreateSetMethod("setNF", nf_field, typeof(int));
            //CreateIncMethod("incNR", "getNR", nr_field);
            //CreateIncMethod("incFNR", "getFNR", fnr_field);
            //CreateResetMethod("resetFNR", fnr_field);
            //CreateAssignVariableMethod(tuples);
        }

        private void CreateAssignVariableMethod(org.jawk.intermediate.AwkTuples tuples)
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    ACC_PUBLIC | ACC_FINAL, GetObjectType(typeof(void)), BuildArgs(new System.Type[]
            //     { typeof(string), typeof(object) }), new string[] { "name", "value" }, "assignVariable"
            //    , classname, il, cp);
            //// basically:
            //// if (name.equals("field1")) field1 = value;
            //// else if (name.equals("field2")) field2 = value;
            //// else if (name.equals("field3")) field3 = value;
            //// ...
            //// else if (name.equals("fieldN")) fieldN = value;
            //// else if (name.equals("funcName1")) throw exception;
            //// else if (name.equals("funcName2")) throw exception;
            //// ...
            //// else if (name.equals("funcNameX")) throw exception;
            //// // otherwise, fall through the method
            //System.Collections.Generic.IDictionary<string, int> global_var_offset_map = tuples
            //    .GetGlobalVariableOffsetMap();
            //System.Collections.Generic.IDictionary<string, bool> global_var_aarray_map = tuples
            //    .GetGlobalVariableAarrayMap();
            //System.Collections.Generic.ICollection<string> function_name_set = tuples.GetFunctionNameSet
            //    ();
            ////assert function_name_set != null;
            //System.Collections.Generic.ICollection<string> all_symbols = new java.util.HashSet
            //    <string>(global_var_offset_map.Keys);
            //Sharpen.Collections.AddAll(all_symbols, function_name_set);
            //// used to just loop over the global_var_offset_map,
            //// but need to loop over vars AND function names
            //// to report errors when trying to use function names
            //// as variable names
            //foreach (string varname in all_symbols)
            //{
            //    // ...
            //    il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_1);
            //    // ..., name
            //    il.Append(new org.apache.bcel.generic.PUSH(cp, varname));
            //    // ..., name, fieldname
            //    il.Append(factory.CreateInvoke(typeof(string).FullName, "equals", org.apache.bcel.generic.Type
            //        .BOOLEAN, BuildArgs(new System.Type[] { typeof(object) }), org.apache.bcel.Constants
            //        .INVOKEVIRTUAL));
            //    // ..., 0-or-1
            //    org.apache.bcel.generic.BranchHandle bh = il.Append(new org.apache.bcel.generic.IFEQ
            //        (null));
            //    // do the assignment!
            //    bool is_function = function_name_set.Contains(varname);
            //    if (is_function)
            //    {
            //        // THROW AN EXCEPTION
            //        // ...
            //        JVMTools_throwNewException(il, typeof(System.ArgumentException), "Cannot assign a scalar to a function name ("
            //             + varname + ").");
            //    }
            //    else
            //    {
            //        int offset = global_var_offset_map[varname];
            //        bool is_aarray = global_var_aarray_map[varname];
            //        if (is_aarray)
            //        {
            //            // THROW AN EXCEPTION
            //            // ...
            //            JVMTools_throwNewException(il, typeof(System.ArgumentException), "Cannot assign a scalar to a non-scalar variable ("
            //                 + varname + ").");
            //        }
            //        else
            //        {
            //            // ...
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //            // ..., this
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_2);
            //            // ..., this, value
            //            il.Append(factory.CreateFieldAccess(classname, "global_" + offset, GetObjectType(
            //                typeof(object)), org.apache.bcel.Constants.PUTFIELD));
            //            // ...
            //            il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //        }
            //    }
            //    // otherwise, fall to the next global field to check
            //    org.apache.bcel.generic.InstructionHandle ih = il.Append(org.apache.bcel.generic.IInstructionConstants
            //        .NOP);
            //    bh.SetTarget(ih);
            //}
            //// or, fall through the method by doing nothing
            //// This occurs when a variable assignment happens
            //// to a var that does not exist within the script.
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private void CreateGetMethod(string method_name, string field_name)
        {
            //CreateGetMethod(ACC_PUBLIC, method_name, field_name);
        }

        private void CreateGetMethod(int method_access, string method_name, string field_name
            )
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    method_access | ACC_FINAL, GetObjectType(typeof(object)), new org.apache.bcel.generic.Type
            //    [] {  }, new string[] {  }, method_name, classname, il, cp);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(factory.CreateFieldAccess(classname, field_name, GetObjectType(typeof(object
            //    )), org.apache.bcel.Constants.GETFIELD));
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            //org.apache.bcel.generic.BranchHandle bh = il.Append(new org.apache.bcel.generic.IFNONNULL
            //    (null));
            //// NULL!
            //il.Append(org.apache.bcel.generic.IInstructionConstants.POP);
            //// pop the null
            //il.Append(new org.apache.bcel.generic.PUSH(cp, string.Empty));
            //org.apache.bcel.generic.InstructionHandle ih = il.Append(factory.CreateReturn(GetObjectType
            //    (typeof(object))));
            //bh.SetTarget(ih);
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private void CreateIncMethod(string method_name, string field_method, string field_name
            )
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //// no-arg method
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    ACC_PUBLIC | ACC_FINAL, org.apache.bcel.generic.Type.VOID, BuildArgs(new System.Type
            //    [] {  }), new string[] {  }, method_name, classname, il, cp);
            //// implement: setXX((int) toDouble(inc(getXX())))
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //// get field
            //il.Append(factory.CreateInvoke(classname, field_method, GetObjectType(typeof(object
            //    )), BuildArgs(new System.Type[] {  }), INVOKEVIRTUAL));
            //// inc
            //il.Append(factory.CreateInvoke(JRT_Class.FullName, "inc", GetObjectType(typeof(object
            //    )), BuildArgs(new System.Type[] { typeof(object) }), INVOKESTATIC));
            //// toDouble
            //il.Append(factory.CreateInvoke(JRT_Class.FullName, "toDouble", GetObjectType(typeof(
            //    double)), BuildArgs(new System.Type[] { typeof(object) }), INVOKESTATIC));
            //// (int)
            //il.Append(org.apache.bcel.generic.IInstructionConstants.D2I);
            //// { convert int to Integer }
            //il.Append(factory.CreateInvoke("java.lang.Integer", "valueOf", GetObjectType(typeof(
            //    int)), BuildArgs(new System.Type[] { typeof(int) }), org.apache.bcel.Constants.
            //    INVOKESTATIC));
            //// set field
            //il.Append(factory.CreateFieldAccess(classname, field_name, GetObjectType(typeof(object
            //    )), org.apache.bcel.Constants.PUTFIELD));
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private void CreateResetMethod(string method_name, string field_name)
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //// no-arg method
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    ACC_PUBLIC | ACC_FINAL, org.apache.bcel.generic.Type.VOID, BuildArgs(new System.Type
            //    [] {  }), new string[] {  }, method_name, classname, il, cp);
            //// implement: setXX(ZERO)
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //    , org.apache.bcel.Constants.GETSTATIC));
            //il.Append(factory.CreateFieldAccess(classname, field_name, GetObjectType(typeof(object
            //    )), org.apache.bcel.Constants.PUTFIELD));
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private void CreateSetMethod(string method_name, string field_name, System.Type field_type
            )
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    ACC_PUBLIC | ACC_FINAL, org.apache.bcel.generic.Type.VOID, BuildArgs(new System.Type
            //    [] { field_type }), new string[] { "arg" }, method_name, classname, il, cp);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_1);
            //il.Append(factory.CreateFieldAccess(classname, field_name, GetObjectType(typeof(object
            //    )), org.apache.bcel.Constants.PUTFIELD));
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private void CreateMethod_getARGV()
        {
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    ACC_PUBLIC | ACC_FINAL, GetObjectType(typeof(object)), new org.apache.bcel.generic.Type
            //    [] {  }, new string[] {  }, "getARGV", classname, il, cp);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(factory.CreateFieldAccess(classname, argv_field, GetObjectType(typeof(object
            //    )), org.apache.bcel.Constants.GETFIELD));
            //il.Append(factory.CreateReturn(GetObjectType(typeof(object))));
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private void GetOffsets(org.jawk.intermediate.AwkTuples tuples)
        {
            org.jawk.intermediate.IPositionForCompilation position = (org.jawk.intermediate.IPositionForCompilation)tuples.Top();
            while (!position.IsEOF())
            {
                int opcode = position.Opcode();
                switch (opcode)
                {
                    case org.jawk.intermediate.AwkTuples._NF_OFFSET_:
                        {
                            nf_field = "global_" + position.IntArg(0);
                            break;
                        }
                    case org.jawk.intermediate.AwkTuples._NR_OFFSET_:
                        {
                            nr_field = "global_" + position.IntArg(0);
                            //il.Append(
                            //    factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int)), org.apache.bcel.Constants.GETSTATIC)
                            //    );
                            JVMTools_storeField(typeof(object), nr_field);
                            break;
                        }
                }
            }

            //while (!position.IsEOF())
            //{
            //    int opcode = position.Opcode();
            //    switch (opcode)
            //    {
            //        case org.jawk.intermediate.AwkTuples._NF_OFFSET_:
            //        {
            //            nf_field = "global_" + position.IntArg(0);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._NR_OFFSET_:
            //        {
            //            nr_field = "global_" + position.IntArg(0);
            //            il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //                , org.apache.bcel.Constants.GETSTATIC));
            //            JVMTools_storeField(typeof(object), nr_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._FNR_OFFSET_:
            //        {
            //            fnr_field = "global_" + position.IntArg(0);
            //            il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //                , org.apache.bcel.Constants.GETSTATIC));
            //            JVMTools_storeField(typeof(object), fnr_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._FS_OFFSET_:
            //        {
            //            fs_field = "global_" + position.IntArg(0);
            //            JVMTools_pushString(" ");
            //            JVMTools_storeField(typeof(object), fs_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._RS_OFFSET_:
            //        {
            //            rs_field = "global_" + (rs_offset = position.IntArg(0));
            //            il.Append(factory.CreateFieldAccess(JRT_Class.FullName, "DEFAULT_RS_REGEX", GetObjectType
            //                (typeof(string)), org.apache.bcel.Constants.GETSTATIC));
            //            JVMTools_storeField(typeof(object), rs_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._OFS_OFFSET_:
            //        {
            //            ofs_field = "global_" + position.IntArg(0);
            //            JVMTools_pushString(" ");
            //            JVMTools_storeField(typeof(object), ofs_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._RSTART_OFFSET_:
            //        {
            //            rstart_field = "global_" + position.IntArg(0);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._RLENGTH_OFFSET_:
            //        {
            //            rlength_field = "global_" + position.IntArg(0);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._FILENAME_OFFSET_:
            //        {
            //            filename_field = "global_" + position.IntArg(0);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._SUBSEP_OFFSET_:
            //        {
            //            subsep_field = "global_" + (subsep_offset = position.IntArg(0));
            //            JVMTools_pushString(new string(new char[] { (char)28 }));
            //            JVMTools_storeField(typeof(object), subsep_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._CONVFMT_OFFSET_:
            //        {
            //            convfmt_offset = position.IntArg(0);
            //            convfmt_field = "global_" + convfmt_offset;
            //            JVMTools_pushString("0.000000");
            //            JVMTools_storeField(typeof(object), convfmt_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._OFMT_OFFSET_:
            //        {
            //            ofmt_field = "global_" + (ofmt_offset = position.IntArg(0));
            //            JVMTools_pushString("0.000000");
            //            JVMTools_storeField(typeof(object), ofmt_field);
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._ENVIRON_OFFSET_:
            //        {
            //            environ_field = "global_" + (environ_offset = position.IntArg(0));
            //            // ...
            //            JVMTools_getVariable(environ_offset, true, true);
            //            // true = global, true = assoc_array
            //            // ... ENVIRON
            //            JVMTools_cast(AssocArrayClass);
            //            // ... (AssocArray) ENVIRON
            //            JVMTools_invokeStatic(typeof(void), JRT_Class, "assignEnvironmentVariables", AssocArrayClass);
            //            // ...
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._ARGC_OFFSET_:
            //        {
            //            argc_field = "global_" + (argc_offset = position.IntArg(0));
            //            break;
            //        }

            //        case org.jawk.intermediate.AwkTuples._ARGV_OFFSET_:
            //        {
            //            argv_field = "global_" + (argv_offset = position.IntArg(0));
            //            // access parameters.name_value_filename_list
            //            // and cycle from 1 to ARGC, populating ARGV
            //            // with the contents of this list as:
            //            // for (...)
            //            //	ARGV[i] = parameters.name_value_filename_list.get(i)
            //            //
            //            // (NVFL = name_value_file_list)
            //            // ...
            //            JVMTools_getVariable(argv_offset, true, true);
            //            // true = is global, true = it is an array
            //            JVMTools_cast(AssocArrayClass);
            //            // ..., Argv
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_1);
            //            // 1st parameter is (AwkParameters) "parameters"
            //            il.Append(factory.CreateFieldAccess(typeof(org.jawk.util.AwkParameters).FullName, 
            //                "name_value_filename_list", GetObjectType(typeof(System.Collections.IList)), org.apache.bcel.Constants
            //                .GETFIELD));
            //            // ..., Argv, NVFL	 (name_value_filename_list)
            //            JVMTools_DUP_X1();
            //            // ..., NVFL, Argv, NVFL
            //            JVMTools_DUP();
            //            JVMTools_invokeInterface(typeof(int), typeof(System.Collections.IList), "size");
            //            // ..., NVFL, Argv, NVFL, argc
            //            // *** set argc here ***
            //            JVMTools_DUP();
            //            // Add one to account for ARGV[0] = "java Awk"
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ICONST_1);
            //            JVMTools_IADD();
            //            JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //            JVMTools_setVariable(argc_offset, true);
            //            // *** done ***
            //            // ..., NVFL, Argv, NVFL, argc
            //            // loop
            //            org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_DUP();
            //            //JVMTools_DEBUG("Within loop!");
            //            //JVMTools_DEBUG(argc_offset, true);	// true = is global
            //            // ..., NVFL, Argv, NVFL, argc, argc
            //            org.apache.bcel.generic.BranchHandle bh = JVMTools_IFEQ();
            //            // argc != 0!
            //            // ..., NVFL, Argv, NVFL, argc
            //            JVMTools_DUP_X2();
            //            JVMTools_DUP_X1();
            //            // ..., NVFL, argc, Argv, argc, NVFL, argc
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, 1));
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ISUB);
            //            JVMTools_invokeInterface(typeof(object), typeof(System.Collections.IList), "get", 
            //                typeof(int));
            //            // ..., NVFL, argc, Argv, argc, item
            //            JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "put", typeof(int), typeof(
            //                object));
            //            JVMTools_POP();
            //            // ..., NVFL, argc
            //            JVMTools_SWAP();
            //            // ..., argc, NVFL
            //            JVMTools_DUP_X1();
            //            // ..., NVFL, argc, NVFL
            //            JVMTools_getVariable(argv_offset, true, true);
            //            // true = is global, true = it is an array
            //            JVMTools_cast(AssocArrayClass);
            //            // ..., NVFL, argc, NVFL, Argv
            //            JVMTools_DUP_X2();
            //            // ..., NVFL, Argv, argc, NVFL, Argv
            //            JVMTools_POP();
            //            // ..., NVFL, Argv, argc, NVFL
            //            JVMTools_SWAP();
            //            // ..., NVFL, Argv, NVFL, argc
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, 1));
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ISUB);
            //            org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //            bh2.SetTarget(ih2);
            //            // ..., NVFL, Argv, NVFL, argc
            //            org.apache.bcel.generic.InstructionHandle ih = JVMTools_POP();
            //            JVMTools_POP();
            //            JVMTools_POP();
            //            JVMTools_POP();
            //            bh.SetTarget(ih);
            //            // set ARGV[0] = "java "+classname
            //            JVMTools_getVariable(argv_offset, true, true);
            //            JVMTools_cast(AssocArrayClass);
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, 0));
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, "java " + classname));
            //            JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "put", typeof(int), typeof(
            //                object));
            //            JVMTools_POP();
            //            break;
            //        }
            //    }
            //    position.Next();
            //}
        }

        /// <summary>
        /// Construct functions that accept a subset of the formal
        /// parameters and pass in null (blank) values for
        /// parameters that are missing.
        /// </summary>
        /// <remarks>
        /// Construct functions that accept a subset of the formal
        /// parameters and pass in null (blank) values for
        /// parameters that are missing.
        /// <p>
        /// The intermediate code (tuples) is traversed one time
        /// to discover all partial parameter calls that are
        /// made.
        /// </remarks>
        private void CreatePartialParamCalls(org.jawk.intermediate.AwkTuples tuples)
        {
            //System.Collections.Generic.IDictionary<string, System.Collections.Generic.ICollection
            //    <int>> visited_funcs = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.ICollection
            //    <int>>();
            //org.jawk.intermediate.IPositionForCompilation position = (org.jawk.intermediate.IPositionForCompilation
            //    )tuples.Top();
            //while (!position.IsEOF())
            //{
            //    int opcode = position.Opcode();
            //    if (opcode == org.jawk.intermediate.AwkTuples._CALL_FUNCTION_)
            //    {
            //        string func_name = position.Arg(1).ToString();
            //        int num_formal_params = position.IntArg(2);
            //        int num_actual_params = position.IntArg(3);
            //        //assert num_formal_params >= num_actual_params;
            //        if (num_formal_params > num_actual_params)
            //        {
            //            System.Collections.Generic.ICollection<int> visited_arg_count = visited_funcs[func_name
            //                ];
            //            if (visited_arg_count == null)
            //            {
            //                visited_funcs[func_name] = visited_arg_count = new java.util.HashSet<int>();
            //            }
            //            if (!visited_arg_count.Contains(num_actual_params))
            //            {
            //                visited_arg_count.Add(num_actual_params);
            //                AddPartialParamCall(func_name, num_formal_params, num_actual_params);
            //            }
            //        }
            //    }
            //    position.Next();
            //}
        }

        private static string[] ToStringArray(System.Collections.Generic.IList<string> list
            )
        {
            string[] retval = new string[list.Count];
            for (int i = 0; i < retval.Length; i++)
            {
                retval[i] = list[i];
            }
            return retval;
        }

        private static System.Type[] ToClassArray(System.Collections.Generic.IList<System.Type
                                                      > list)
        {
            System.Type[] retval = new System.Type[list.Count];
            for (int i = 0; i < retval.Length; i++)
            {
                retval[i] = list[i];
            }
            return retval;
        }

        private void AddPartialParamCall(string func_name, int num_formal_params, int num_actual_params
            )
        {
            ////System.err.println("PARTIAL_PARAM_CALL: "+func_name+" - "+num_formal_params+" - "+num_actual_params);
            //// condition the argument parameters
            //System.Collections.Generic.IList<System.Type> arg_classes = new System.Collections.Generic.List
            //    <System.Type>();
            //System.Collections.Generic.IList<string> arg_names = new System.Collections.Generic.List
            //    <string>();
            //System.Collections.Generic.IDictionary<string, int> local_vars = new System.Collections.Generic.Dictionary
            //    <string, int>();
            //for (int i = num_actual_params - 1; i >= 0; --i)
            //{
            //    arg_classes.Add(typeof(object));
            //    arg_names.Add("locals_" + i);
            //    local_vars["locals_" + i] = local_vars.Count + 1;
            //}
            //org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList
            //    ();
            //org.apache.bcel.generic.MethodGen method = new org.apache.bcel.generic.MethodGen(
            //    ACC_PUBLIC | ACC_FINAL, GetObjectType(typeof(object)), BuildArgs(ToClassArray(arg_classes
            //    )), ToStringArray(arg_names), "FUNC_" + func_name, classname, il, cp);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //arg_classes.Clear();
            //for (int i = num_formal_params - 1; i >= 0; --i)
            //{
            //    arg_classes.Add(typeof(object));
            //    if (i >= num_actual_params)
            //    {
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ACONST_NULL);
            //    }
            //    else
            //    {
            //        il.Append(factory.CreateLoad(GetObjectType(typeof(object)), local_vars["locals_" 
            //            + i]));
            //    }
            //}
            //il.Append(factory.CreateInvoke(classname, "FUNC_" + func_name, GetObjectType(typeof(
            //    object)), BuildArgs(ToClassArray(arg_classes)), org.apache.bcel.Constants.INVOKEVIRTUAL
            //    ));
            //il.Append(factory.CreateReturn(GetObjectType(typeof(object))));
            //method.SetMaxStack();
            //method.SetMaxLocals();
            //cg.AddMethod(method.GetMethod());
            //il.Dispose();
        }

        private org.jawk.intermediate.IAddress exit_address;

        private System.Collections.Generic.IDictionary<org.jawk.intermediate.IAddress, System.Collections.Generic.IList
            <org.apache.bcel.generic.BranchHandle>> branch_handles = new System.Collections.Generic.Dictionary
                <org.jawk.intermediate.IAddress, System.Collections.Generic.IList<org.apache.bcel.generic.BranchHandle
                    >>();

        private System.Collections.Generic.IDictionary<int, org.apache.bcel.generic.InstructionHandle
            > instruction_handles =
                new System.Collections.Generic.Dictionary<int, org.apache.bcel.generic.InstructionHandle
                    >();

        private string nf_field = null;

        private string nr_field = null;

        private string fnr_field = null;

        private string fs_field = null;

        private string rs_field = null;

        private string ofs_field = null;

        private string rstart_field = null;

        private string rlength_field = null;

        private string filename_field = null;

        private string subsep_field = null;

        private string convfmt_field = null;

        private string ofmt_field = null;

        private string environ_field = null;

        private string argc_field = null;

        private string argv_field = null;

        private int convfmt_offset = -1;

        private int environ_offset = -1;

        private int subsep_offset = -1;

        private int ofmt_offset = -1;

        private int argv_offset = -1;

        private int argc_offset = -1;

        private int rs_offset = -1;

        private int ps_arg_idx = 0;

        private int fmt_arg_idx = 0;

        private int arr_idx_arg_idx = 0;

        // tuples provided only in the event of dumping global variables to stdout
        // via the _DUMP extension
        private void TranslateToJVM(org.jawk.intermediate.IPositionForCompilation position
                                    , int opcode, org.jawk.intermediate.AwkTuples tuples)
        {
            //switch (opcode)
            //{
            //    case org.jawk.intermediate.AwkTuples._SET_EXIT_ADDRESS_:
            //    {
            //        exit_address = position.AddressArg();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._GOTO_:
            //    {
            //        JVMTools_GOTO(position.AddressArg());
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SET_NUM_GLOBALS_:
            //    {
            //        //assert mg_temp == null && il_temp == null || mg_temp != null && il_temp != null;
            //        if (mg_temp != null)
            //        {
            //            ResolveBranchHandleTargets();
            //            mg.SetMaxStack();
            //            mg.SetMaxLocals();
            //            cg.AddMethod(mg.GetMethod());
            //            il.Dispose();
            //            mg = mg_temp;
            //            il = il_temp;
            //            branch_handles = bhs_temp;
            //            instruction_handles = ihs_temp;
            //            local_vars = lvs_temp;
            //        }
            //        // else , do nothing
            //        int num_globals = position.IntArg(0);
            //        for (int i = 0; i < num_globals; i++)
            //        {
            //            JVMTools_allocateField(typeof(object), "global_" + i);
            //        }
            //        // process initial_variables list from "parameters" parameter
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_1);
            //        // 1st parameter is (AwkParameters) "parameters"
            //        il.Append(factory.CreateFieldAccess(typeof(org.jawk.util.AwkParameters).FullName, 
            //            "initial_variables", GetObjectType(typeof(System.Collections.IDictionary)), org.apache.bcel.Constants
            //            .GETFIELD));
            //        // ..., JRT, Map
            //        // cycle through the map, assigning variables that exist
            //        JVMTools_invokeVirtual(typeof(void), JRT_Class, "assignInitialVariables", typeof(
            //            System.Collections.IDictionary));
            //        // (done)
            //        //JVMTools_NOP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PUSH_:
            //    {
            //        object arg = position.Arg(0);
            //        if (false)
            //        {
            //        }
            //        else
            //        {
            //            if (arg is int)
            //            {
            //                JVMTools_pushInteger(((int)arg));
            //            }
            //            else
            //            {
            //                if (arg is double)
            //                {
            //                    JVMTools_pushDouble(((double)arg));
            //                }
            //                else
            //                {
            //                    if (arg is string)
            //                    {
            //                        JVMTools_pushString(arg.ToString());
            //                    }
            //                    else
            //                    {
            //                        throw new System.Exception("Invalid position arg: " + arg + " (" + arg.GetType().
            //                            FullName + ")");
            //                    }
            //                }
            //            }
            //        }
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._IFFALSE_:
            //    {
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(bool), JRT_Class, "toBoolean", typeof(object));
            //        JVMTools_IFEQ(position.AddressArg());
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._IFTRUE_:
            //    {
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(bool), JRT_Class, "toBoolean", typeof(object));
            //        JVMTools_IFNE(position.AddressArg());
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._NOT_:
            //    {
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(bool), JRT_Class, "toBoolean", typeof(object));
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNE();
            //        il.Append(factory.CreateFieldAccess(classname, "ONE", GetObjectType(typeof(int)), 
            //            org.apache.bcel.Constants.GETSTATIC));
            //        org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //        org.apache.bcel.generic.InstructionHandle ih = il.Append(factory.CreateFieldAccess
            //            (classname, "ZERO", GetObjectType(typeof(int)), org.apache.bcel.Constants.GETSTATIC
            //            ));
            //        bh.SetTarget(ih);
            //        org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_NOP();
            //        bh2.SetTarget(ih2);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._NOP_:
            //    {
            //        JVMTools_NOP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SET_WITHIN_END_BLOCKS_:
            //    {
            //        //assert il == il_main;
            //        // put a RETURN at the end of ScriptMain
            //        AddExitCode(il_main, mg_main);
            //        il = il_reb;
            //        mg = mg_reb;
            //        local_vars = lv_reb;
            //        // just to ensure something in runEndBlocks
            //        // because if not, setMaxLocals will fail
            //        JVMTools_NOP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PRINT_:
            //    {
            //        org.apache.bcel.generic.MethodGen lmg = mg;
            //        // ..., {args}
            //        int num_args = position.IntArg(0);
            //        if (num_args == 0)
            //        {
            //            // WITHOUT arguments
            //            // (use $0)
            //            il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //                , org.apache.bcel.Constants.GETSTATIC));
            //            GetInputField();
            //            num_args = 1;
            //        }
            //        // ..., $0
            //        //assert num_args >= 1;
            //        for (int i = 0; i < num_args; i++)
            //        {
            //            // stack contains objects
            //            //JVMTools_DEBUG_TOS();	// TOS = top-of-stack
            //            // ..., {args}, arg
            //            JVMTools_toAwkStringForOutput();
            //            JVMTools_printString();
            //            // ..., {args}
            //            if (i < num_args - 1)
            //            {
            //                JVMTools_getField(typeof(object), ofs_field);
            //                JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //                // if OFS is "", use " "
            //                JVMTools_DUP();
            //                org.apache.bcel.generic.BranchHandle bh = JVMTools_ifStringNotEquals(string.Empty
            //                    );
            //                JVMTools_POP();
            //                JVMTools_pushString(" ");
            //                org.apache.bcel.generic.InstructionHandle ih = JVMTools_NOP();
            //                bh.SetTarget(ih);
            //                // ..., {args}, OFS
            //                JVMTools_printString();
            //            }
            //        }
            //        // ..., {args}
            //        // ...
            //        JVMTools_println();
            //        // ...
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PRINT_TO_FILE_:
            //    case org.jawk.intermediate.AwkTuples._PRINT_TO_PIPE_:
            //    {
            //        // ..., argN, ..., arg2, arg1, output-filename or cmd-string
            //        int num_args = position.IntArg(0);
            //        if (num_args == 0)
            //        {
            //            // WITHOUT arguments
            //            // (use $0)
            //            il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //                , org.apache.bcel.Constants.GETSTATIC));
            //            GetInputField();
            //            JVMTools_SWAP();
            //            num_args = 1;
            //        }
            //        // ..., $0, output-filename or cmd-string
            //        //assert num_args >= 1;
            //        // ..., argN, ..., arg2, arg1, output-filename or cmd-string
            //        // convert output-filename or cmd-string to printstream
            //        JVMTools_toAwkString();
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._PRINT_TO_FILE_:
            //            {
            //                bool append = position.BoolArg(1);
            //                // true = append to file
            //                il.Append(new org.apache.bcel.generic.PUSH(cp, append));
            //                // [...], JRT, output-filename, append
            //                JVMTools_invokeVirtual(typeof(System.IO.TextWriter), JRT_Class, "jrtGetPrintStream"
            //                    , typeof(string), typeof(bool));
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._PRINT_TO_PIPE_:
            //            {
            //                JVMTools_invokeVirtual(typeof(System.IO.TextWriter), JRT_Class, "jrtSpawnForOutput"
            //                    , typeof(string));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for print to file or pipe: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        // ..., argN, ..., arg2, arg1, ps
            //        for (int i = 0; i < num_args; i++)
            //        {
            //            // stack contains objects
            //            JVMTools_SWAP();
            //            JVMTools_toAwkStringForOutput();
            //            JVMTools_SWAP();
            //            JVMTools_printStringWithPS();
            //            if (i < num_args - 1)
            //            {
            //                JVMTools_getField(typeof(object), ofs_field);
            //                JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //                // if OFS is "", use " "
            //                JVMTools_DUP();
            //                org.apache.bcel.generic.BranchHandle bh = JVMTools_ifStringNotEquals(string.Empty
            //                    );
            //                JVMTools_POP();
            //                JVMTools_pushString(" ");
            //                org.apache.bcel.generic.InstructionHandle ih = JVMTools_SWAP();
            //                bh.SetTarget(ih);
            //                JVMTools_printStringWithPS();
            //            }
            //        }
            //        JVMTools_printlnWithPS();
            //        JVMTools_POP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PRINTF_:
            //    case org.jawk.intermediate.AwkTuples._SPRINTF_:
            //    {
            //        org.apache.bcel.generic.MethodGen lmg = mg;
            //        int num_args = position.IntArg(0);
            //        // ..., {args}
            //        JVMTools_toAwkString();
            //        org.apache.bcel.generic.LocalVariableGen fmt_arg = lmg.AddLocalVariable("fmt_arg_"
            //             + (++fmt_arg_idx), GetObjectType(typeof(string)), null, null);
            //        org.apache.bcel.generic.InstructionHandle ih = il.Append(factory.CreateStore(GetObjectType
            //            (typeof(string)), fmt_arg.GetIndex()));
            //        fmt_arg.SetStart(ih);
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, num_args - 1));
            //        il.Append(factory.CreateNewArray(GetObjectType(typeof(object)), (short)1));
            //        // ..., {args}, array
            //        for (int i = 0; i < num_args - 1; i++)
            //        {
            //            // ..., {args}, array
            //            JVMTools_DUP_X1();
            //            // ..., {args}, array, arg, array
            //            JVMTools_SWAP();
            //            // ..., {args}, array, array, arg
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, i));
            //            // ..., {args}, array, array, arg, i
            //            JVMTools_SWAP();
            //            // ..., {args}, array, array, i, arg
            //            il.Append(factory.CreateArrayStore(GetObjectType(typeof(object))));
            //        }
            //        // ..., {args}, array
            //        // ..., array
            //        il.Append(factory.CreateLoad(GetObjectType(typeof(string)), fmt_arg.GetIndex()));
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._PRINTF_:
            //            {
            //                JVMTools_invokeStatic(typeof(void), JRT_Class, parameters.trap_illegal_format_exceptions
            //                     ? "printfFunction" : "printfFunctionNoCatch", typeof(object[]), typeof(string));
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._SPRINTF_:
            //            {
            //                JVMTools_invokeStatic(typeof(string), JRT_Class, parameters.trap_illegal_format_exceptions
            //                     ? "sprintfFunction" : "sprintfFunctionNoCatch", typeof(object[]), typeof(string
            //                    ));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for [s]printf: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PRINTF_TO_FILE_:
            //    case org.jawk.intermediate.AwkTuples._PRINTF_TO_PIPE_:
            //    {
            //        org.apache.bcel.generic.MethodGen lmg = mg;
            //        int num_args = position.IntArg(0);
            //        // ..., {args-with-fmt}, output-filename or cmd-string
            //        // convert output-filename or cmd-string to printstream
            //        JVMTools_toAwkString();
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._PRINTF_TO_FILE_:
            //            {
            //                bool append = position.BoolArg(1);
            //                il.Append(new org.apache.bcel.generic.PUSH(cp, append));
            //                JVMTools_invokeVirtual(typeof(System.IO.TextWriter), JRT_Class, "jrtGetPrintStream"
            //                    , typeof(string), typeof(bool));
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._PRINTF_TO_PIPE_:
            //            {
            //                JVMTools_invokeVirtual(typeof(System.IO.TextWriter), JRT_Class, "jrtSpawnForOutput"
            //                    , typeof(string));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for printf to file or pipe: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        // ..., {args-with-fmt}, ps
            //        // deal with the format string
            //        JVMTools_SWAP();
            //        JVMTools_toAwkString();
            //        // ..., {args}, ps, format_string
            //        org.apache.bcel.generic.LocalVariableGen fmt_arg = lmg.AddLocalVariable("fmt_arg_"
            //             + (++fmt_arg_idx), GetObjectType(typeof(string)), null, null);
            //        org.apache.bcel.generic.InstructionHandle ih = il.Append(factory.CreateStore(GetObjectType
            //            (typeof(string)), fmt_arg.GetIndex()));
            //        fmt_arg.SetStart(ih);
            //        // ..., {args}, ps
            //        JVMTools_SWAP();
            //        // ..., {args-1}, ps, arg
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, num_args - 1));
            //        il.Append(factory.CreateNewArray(GetObjectType(typeof(object)), (short)1));
            //        // ..., {args-1}, ps, arg, array
            //        for (int i = 0; i < num_args - 1; i++)
            //        {
            //            // ..., {args-rest}, ps, arg, array
            //            JVMTools_DUP_X1();
            //            // ..., {args}, ps, array, arg, array
            //            JVMTools_SWAP();
            //            // ..., {args}, ps, array, array, arg
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, i));
            //            // ..., {args}, ps, array, array, arg, i
            //            JVMTools_SWAP();
            //            // ..., {args}, ps, array, array, i, arg
            //            il.Append(factory.CreateArrayStore(GetObjectType(typeof(object))));
            //            // ..., {args}, ps, array
            //            if (i != num_args - 2)
            //            {
            //                // ..., {args}, ps, array
            //                JVMTools_DUP_X2();
            //                JVMTools_POP();
            //                // ..., {args}, array, arg, ps
            //                JVMTools_DUP_X2();
            //                JVMTools_POP();
            //                // ..., {args}, ps, array, arg
            //                JVMTools_SWAP();
            //            }
            //        }
            //        // ..., {args}, ps, arg, array
            //        // ..., ps, array
            //        il.Append(factory.CreateLoad(GetObjectType(typeof(string)), fmt_arg.GetIndex()));
            //        // ..., ps, array, fmt_arg
            //        JVMTools_invokeStatic(typeof(void), JRT_Class, parameters.trap_illegal_format_exceptions
            //             ? "printfFunction" : "printfFunctionNoCatch", typeof(System.IO.TextWriter), typeof(
            //            object[]), typeof(string));
            //        // ...
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CONCAT_:
            //    {
            //        // ..., arg2, arg1
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        // ..., arg2, arg1, sb
            //        JVMTools_DUP();
            //        // ..., arg2, arg1, sb, sb
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ICONST_0);
            //        // ..., arg2, arg1, sb, sb, 0
            //        JVMTools_invokeVirtual(typeof(void), typeof(System.Text.StringBuilder), "setLength"
            //            , typeof(int));
            //        // ..., arg2, arg1, sb
            //        JVMTools_SWAP();
            //        // ..., arg2, sb, arg1
            //        JVMTools_toAwkString();
            //        JVMTools_invokeVirtual(typeof(System.Text.StringBuilder), typeof(System.Text.StringBuilder
            //            ), "append", typeof(string));
            //        // ..., arg2, sb
            //        JVMTools_SWAP();
            //        // ..., sb, arg2
            //        JVMTools_toAwkString();
            //        JVMTools_invokeVirtual(typeof(System.Text.StringBuilder), typeof(System.Text.StringBuilder
            //            ), "append", typeof(string));
            //        JVMTools_invokeVirtual(typeof(string), typeof(System.Text.StringBuilder), "toString"
            //            );
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._ASSIGN_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        JVMTools_DUP();
            //        JVMTools_setVariable(offset, is_global);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._ASSIGN_ARRAY_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        // ..., value, array_index
            //        JVMTools_SWAP();
            //        // ..., array_index, value
            //        JVMTools_DUP_X1();
            //        // ..., value, array_index, value
            //        JVMTools_getVariable(offset, is_global, true);
            //        // true = it is an array
            //        JVMTools_cast(AssocArrayClass);
            //        // ..., value, array_index, value, assocarray
            //        JVMTools_DUP_X2();
            //        JVMTools_POP();
            //        // ..., value, assoc_array, array_index, value
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "put", typeof(object), typeof(
            //            object));
            //        JVMTools_POP();
            //        // value is left on the stack
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._APPLY_SUBSEP_:
            //    {
            //        int num_args = position.IntArg(0);
            //        // ..., arg2, arg1
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        // ..., arg1, arg2, ..., argN, sb
            //        // (assume 2 args here)
            //        JVMTools_DUP();
            //        // ..., arg1, arg2, sb, sb
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ICONST_0);
            //        // ..., arg1, arg2, sb, sb, 0
            //        JVMTools_invokeVirtual(typeof(void), typeof(System.Text.StringBuilder), "setLength"
            //            , typeof(int));
            //        // ..., arg1, arg2, sb
            //        for (int i = 0; i < num_args; i++)
            //        {
            //            if (i > 0)
            //            {
            //                il.Append(org.apache.bcel.generic.IInstructionConstants.ICONST_0);
            //                JVMTools_getVariable(subsep_offset, true, false);
            //                // true = is_global, false = is NOT array
            //                JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //                JVMTools_invokeVirtual(typeof(System.Text.StringBuilder), typeof(System.Text.StringBuilder
            //                    ), "insert", typeof(int), typeof(string));
            //            }
            //            JVMTools_SWAP();
            //            // ..., arg1, sb, arg2
            //            JVMTools_toAwkString();
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ICONST_0);
            //            JVMTools_SWAP();
            //            JVMTools_invokeVirtual(typeof(System.Text.StringBuilder), typeof(System.Text.StringBuilder
            //                ), "insert", typeof(int), typeof(string));
            //        }
            //        JVMTools_invokeVirtual(typeof(string), typeof(System.Text.StringBuilder), "toString"
            //            );
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._KEYLIST_:
            //    {
            //        JVMTools_cast(AssocArrayClass);
            //        JVMTools_invokeVirtual(typeof(java.util.ISet), AssocArrayClass, "keySet");
            //        JVMTools_new(KeyListImplClass.FullName, typeof(java.util.ISet));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DUP_:
            //    {
            //        JVMTools_DUP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CHECK_CLASS_:
            //    {
            //        JVMTools_cast(position.ClassArg());
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._IS_EMPTY_KEYLIST_:
            //    {
            //        JVMTools_invokeInterface(typeof(int), typeof(org.jawk.jrt.IKeyList), "size");
            //        JVMTools_IFEQ(position.AddressArg());
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._GET_FIRST_AND_REMOVE_FROM_KEYLIST_:
            //    {
            //        JVMTools_invokeInterface(typeof(object), typeof(org.jawk.jrt.IKeyList), "getFirstAndRemove"
            //            );
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._POP_:
            //    {
            //        JVMTools_POP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SWAP_:
            //    {
            //        JVMTools_SWAP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DEREFERENCE_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_array = position.BoolArg(1);
            //        bool is_global = position.BoolArg(2);
            //        JVMTools_getVariable(offset, is_global, is_array);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DEREF_ARRAY_:
            //    {
            //        JVMTools_DUP();
            //        JVMTools_instanceOf(AssocArrayClass);
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNE();
            //        // not an AssocArray
            //        JVMTools_throwNewException(AwkRuntimeExceptionClass, "Attempting to index to a non-associative array."
            //            );
            //        // an AssocArray
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_cast(AssocArrayClass);
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "get", typeof(object));
            //        bh.SetTarget(ih);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CAST_INT_:
            //    case org.jawk.intermediate.AwkTuples._INTFUNC_:
            //    {
            //        JVMTools_toDouble();
            //        JVMTools_D2I();
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CAST_DOUBLE_:
            //    {
            //        JVMTools_toDouble();
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CAST_STRING_:
            //    {
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._NEGATE_:
            //    {
            //        JVMTools_toDouble();
            //        JVMTools_DNEG();
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._ADD_:
            //    {
            //        JVMTools_toDouble(2);
            //        // 2 = num reference arguments
            //        JVMTools_DADD();
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SUBTRACT_:
            //    {
            //        JVMTools_toDouble(2);
            //        // 2 = num reference arguments
            //        JVMTools_DSUB();
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._MULTIPLY_:
            //    {
            //        JVMTools_toDouble(2);
            //        // 2 = num reference arguments
            //        JVMTools_DMUL();
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DIVIDE_:
            //    {
            //        JVMTools_toDouble(2);
            //        // 2 = num reference arguments
            //        JVMTools_DDIV();
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._MOD_:
            //    {
            //        JVMTools_toDouble(2);
            //        // 2 = num reference arguments
            //        JVMTools_DREM();
            //        // double remainder
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._POW_:
            //    {
            //        JVMTools_toDouble(2);
            //        // 2 = num reference arguments
            //        // execute Math.pow
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "pow", typeof(double), 
            //            typeof(double));
            //        JVMTools_fromDoubleToNumber();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PLUS_EQ_:
            //    case org.jawk.intermediate.AwkTuples._MINUS_EQ_:
            //    case org.jawk.intermediate.AwkTuples._MULT_EQ_:
            //    case org.jawk.intermediate.AwkTuples._DIV_EQ_:
            //    case org.jawk.intermediate.AwkTuples._MOD_EQ_:
            //    case org.jawk.intermediate.AwkTuples._POW_EQ_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        JVMTools_getVariable(offset, is_global, false);
            //        // false = not an array
            //        JVMTools_toDouble(2);
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._PLUS_EQ_:
            //            {
            //                JVMTools_DADD();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MINUS_EQ_:
            //            {
            //                JVMTools_DSUB();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MULT_EQ_:
            //            {
            //                JVMTools_DMUL();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._DIV_EQ_:
            //            {
            //                JVMTools_DDIV();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MOD_EQ_:
            //            {
            //                JVMTools_DREM();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._POW_EQ_:
            //            {
            //                JVMTools_invokeStatic(typeof(double), typeof(System.Math), "pow", typeof(double), 
            //                    typeof(double));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Unknown opcode: " + org.jawk.intermediate.AwkTuples.ToOpcodeString
            //                    (opcode));
            //            }
            //        }
            //        JVMTools_fromDoubleToNumber();
            //        // keep the result on the stack (a+=b evaluates to the result)
            //        JVMTools_DUP();
            //        JVMTools_setVariable(offset, is_global);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PLUS_EQ_ARRAY_:
            //    case org.jawk.intermediate.AwkTuples._MINUS_EQ_ARRAY_:
            //    case org.jawk.intermediate.AwkTuples._MULT_EQ_ARRAY_:
            //    case org.jawk.intermediate.AwkTuples._DIV_EQ_ARRAY_:
            //    case org.jawk.intermediate.AwkTuples._MOD_EQ_ARRAY_:
            //    case org.jawk.intermediate.AwkTuples._POW_EQ_ARRAY_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        // ..., value, array-idx
            //        JVMTools_DUP_X1();
            //        // ..., array-idx, value, array-idx
            //        JVMTools_getVariable(offset, is_global, true);
            //        // true = an array
            //        JVMTools_cast(AssocArrayClass);
            //        // ..., array-idx, value, array-idx, AssocArray
            //        JVMTools_DUP_X2();
            //        JVMTools_SWAP();
            //        // ..., array-idx, AssocArray, value, AssocArray, array-idx
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "get", typeof(object));
            //        // ..., array-idx, AssocArray, value, orig-value
            //        JVMTools_toDouble(2);
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._PLUS_EQ_ARRAY_:
            //            {
            //                // ..., array-idx, AssocArray, orig-value, value
            //                JVMTools_DADD();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MINUS_EQ_ARRAY_:
            //            {
            //                JVMTools_DSUB();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MULT_EQ_ARRAY_:
            //            {
            //                JVMTools_DMUL();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._DIV_EQ_ARRAY_:
            //            {
            //                JVMTools_DDIV();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MOD_EQ_ARRAY_:
            //            {
            //                JVMTools_DREM();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._POW_EQ_ARRAY_:
            //            {
            //                JVMTools_invokeStatic(typeof(double), typeof(System.Math), "pow", typeof(double), 
            //                    typeof(double));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Unknown opcode: " + org.jawk.intermediate.AwkTuples.ToOpcodeString
            //                    (opcode));
            //            }
            //        }
            //        JVMTools_fromDoubleToNumber();
            //        // ..., array-idx, AssocArray, new-value
            //        JVMTools_SWAP();
            //        JVMTools_DUP_X2();
            //        JVMTools_POP();
            //        // ..., AssocArray, array-idx, new-value
            //        JVMTools_DUP_X2();
            //        // ..., new-value, AssocArray, array-idx, new-value
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "put", typeof(object), typeof(
            //            object));
            //        // ..., new-value, old-value
            //        JVMTools_POP();
            //        // ..., new-value
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CMP_LT_:
            //    {
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, 1));
            //        // reverse because items are swapped on the stack
            //        JVMTools_invokeStatic(typeof(bool), JRT_Class, "compare2", typeof(object), typeof(
            //            object), typeof(int));
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CMP_GT_:
            //    {
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, -1));
            //        // reverse because items are swapped on the stack
            //        JVMTools_invokeStatic(typeof(bool), JRT_Class, "compare2", typeof(object), typeof(
            //            object), typeof(int));
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CMP_EQ_:
            //    {
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, 0));
            //        // reverse because items are swapped on the stack
            //        JVMTools_invokeStatic(typeof(bool), JRT_Class, "compare2", typeof(object), typeof(
            //            object), typeof(int));
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._INC_:
            //    case org.jawk.intermediate.AwkTuples._DEC_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        JVMTools_getVariable(offset, is_global, false);
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._INC_:
            //            {
            //                // false = not an array
            //                JVMTools_invokeStatic(typeof(object), JRT_Class, "inc", typeof(object));
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._DEC_:
            //            {
            //                JVMTools_invokeStatic(typeof(object), JRT_Class, "dec", typeof(object));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for inc/dec: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        JVMTools_setVariable(offset, is_global);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._INC_ARRAY_REF_:
            //    case org.jawk.intermediate.AwkTuples._DEC_ARRAY_REF_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        // ..., idx
            //        JVMTools_DUP();
            //        // ..., idx, idx
            //        JVMTools_getVariable(offset, is_global, true);
            //        // true = is array
            //        JVMTools_cast(AssocArrayClass);
            //        // ..., idx, idx, aa
            //        JVMTools_DUP_X2();
            //        // ..., aa, idx, idx, aa
            //        JVMTools_SWAP();
            //        // ..., aa, idx, aa, idx
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "get", typeof(object));
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._INC_ARRAY_REF_:
            //            {
            //                // ..., aa, idx, item
            //                JVMTools_invokeStatic(typeof(object), JRT_Class, "inc", typeof(object));
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._DEC_ARRAY_REF_:
            //            {
            //                JVMTools_invokeStatic(typeof(object), JRT_Class, "dec", typeof(object));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for inc/dec array ref: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        // ..., item+1, aa, idx, item+/-1
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "put", typeof(object), typeof(
            //            object));
            //        JVMTools_POP();
            //        // ..., item+/-1
            //        // ITEM IS LEFT ON THE STACK
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._EXIT_WITH_CODE_:
            //    {
            //        JVMTools_toDouble();
            //        JVMTools_D2I();
            //        JVMTools_storeField(typeof(int), "exit_code");
            //        // throw EndException here
            //        JVMTools_throwNewException(EndExceptionClass, "exit() called");
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._FUNCTION_:
            //    {
            //        string func_name = position.Arg(0).ToString();
            //        int num_params = position.IntArg(1);
            //        //assert mg_temp == null && il_temp == null || mg_temp != null && il_temp != null;
            //        if (mg_temp != null)
            //        {
            //            ResolveBranchHandleTargets();
            //            mg.SetMaxStack();
            //            mg.SetMaxLocals();
            //            cg.AddMethod(mg.GetMethod());
            //            il.Dispose();
            //        }
            //        else
            //        {
            //            mg_temp = mg;
            //            il_temp = il;
            //            bhs_temp = branch_handles;
            //            ihs_temp = instruction_handles;
            //            lvs_temp = local_vars;
            //        }
            //        // build arg array
            //        org.apache.bcel.generic.Type[] @params = new org.apache.bcel.generic.Type[num_params
            //            ];
            //        string[] names = new string[num_params];
            //        for (int i = 0; i < num_params; i++)
            //        {
            //            @params[i] = GetObjectType(typeof(object));
            //            names[i] = "locals_" + (num_params - i - 1);
            //        }
            //        il = new org.jawk.backend.AwkCompilerImpl.MyInstructionList();
            //        mg = new org.apache.bcel.generic.MethodGen(ACC_PUBLIC, org.apache.bcel.generic.Type
            //            .OBJECT, @params, names, "FUNC_" + func_name, classname, il, cp);
            //        branch_handles = new System.Collections.Generic.Dictionary<org.jawk.intermediate.IAddress
            //            , System.Collections.Generic.IList<org.apache.bcel.generic.BranchHandle>>();
            //        instruction_handles = new System.Collections.Generic.Dictionary<int, org.apache.bcel.generic.InstructionHandle
            //            >();
            //        local_vars = new System.Collections.Generic.Dictionary<string, int>();
            //        // so the JVMTools knows about the parameters like it does for local variables
            //        JVMTools_allocateFunctionParameters(names);
            //        JVMTools_allocateLocalVariable(typeof(object), "_return_value_");
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ACONST_NULL);
            //        JVMTools_storeToLocalVariable(typeof(object), "_return_value_");
            //        JVMTools_allocateLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_new("java.lang.StringBuffer");
            //        JVMTools_storeToLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_allocateLocalVariable(typeof(double), "dregister");
            //        // bug with BCEL:
            //        // an access to this variable is crucial... otherwise,
            //        // setMaxLocals() fails to account for it,
            //        // causing a corrupt class file error upon invocation
            //        // of the JVM
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, 0.0));
            //        JVMTools_storeToLocalVariable(typeof(double), "dregister");
            //        JVMTools_NOP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SET_RETURN_RESULT_:
            //    {
            //        // return value already on the stack
            //        JVMTools_storeToLocalVariable(typeof(object), "_return_value_");
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._RETURN_FROM_FUNCTION_:
            //    {
            //        JVMTools_getLocalVariable(typeof(object), "_return_value_");
            //        il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.OBJECT));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._THIS_:
            //    {
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CALL_FUNCTION_:
            //    {
            //        // do nothing, for now
            //        string func_name = position.Arg(1).ToString();
            //        int num_formal_params = position.IntArg(2);
            //        int num_actual_params = position.IntArg(3);
            //        //assert num_formal_params >= num_actual_params;
            //        // what will occur is the following:
            //        // - multiple arg verions of the method
            //        // - each version simply *pre*-pads the arg list with NULLs
            //        // - every "local" access is a reverse-offset into the arg list
            //        // by this time, all callable/called variations of the
            //        // method have been defined
            //        // therefore, just call the method
            //        // build arg list
            //        System.Type[] arg_array = new System.Type[num_actual_params];
            //        for (int i = 0; i < num_actual_params; i++)
            //        {
            //            arg_array[i] = typeof(object);
            //        }
            //        il.Append(factory.CreateInvoke(classname, "FUNC_" + func_name, GetObjectType(typeof(
            //            object)), BuildArgs(arg_array), INVOKEVIRTUAL));
            //        // check for NULL return value
            //        JVMTools_DUP();
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNONNULL();
            //        JVMTools_POP();
            //        JVMTools_pushString(string.Empty);
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_NOP();
            //        bh.SetTarget(ih);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._REGEXP_:
            //    {
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, (string)position.Arg(0)));
            //        JVMTools_toAwkString();
            //        JVMTools_DUP();
            //        // ..., regexp_str, regexp_str
            //        JVMTools_getField(typeof(System.Collections.IDictionary), "regexps");
            //        JVMTools_SWAP();
            //        JVMTools_invokeInterface(typeof(object), typeof(System.Collections.IDictionary), 
            //            "get", typeof(object));
            //        // ..., regexp_str, Pattern-or-NULL
            //        JVMTools_DUP();
            //        // ..., regexp_str, Pattern-or-NULL, Pattern-or-NULL
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNONNULL();
            //        // regexp doesn't exist in the Map
            //        JVMTools_POP();
            //        JVMTools_DUP();
            //        // ..., regexp_str, regexp_str
            //        JVMTools_invokeStatic(typeof(java.util.regex.Pattern), typeof(java.util.regex.Pattern
            //            ), "compile", typeof(string));
            //        // ..., regexp_str, Pattern
            //        JVMTools_DUP_X1();
            //        // ..., Pattern, regexp_str, Pattern
            //        JVMTools_getField(typeof(System.Collections.IDictionary), "regexps");
            //        JVMTools_DUP_X2();
            //        JVMTools_POP();
            //        // ..., Pattern, regexps, regexp_str, Pattern
            //        JVMTools_invokeInterface(typeof(object), typeof(System.Collections.IDictionary), 
            //            "put", typeof(object), typeof(object));
            //        JVMTools_POP();
            //        // ..., Pattern
            //        org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //        // end
            //        // ..., regexp_str, Pattern-or-NULL
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_SWAP();
            //        bh.SetTarget(ih);
            //        JVMTools_POP();
            //        // ..., Pattern-or-NULL
            //        org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_NOP();
            //        bh2.SetTarget(ih2);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._REGEXP_PAIR_:
            //    {
            //        // ..., regexp2 (string), regexp1 (string)
            //        JVMTools_getField(typeof(System.Collections.IDictionary), "pattern_pairs");
            //        // ..., regexp2, regexp1, pattern_pairs
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, position.Index()));
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        // ..., regexp2, regexp1, pattern_pairs, pos-idx
            //        JVMTools_invokeInterface(typeof(object), typeof(System.Collections.IDictionary), 
            //            "get", typeof(object));
            //        // ..., regexp2, regexp1, pattern_pair
            //        JVMTools_DUP();
            //        // ..., regexp2, regexp1, pattern_pair, pattern_pair
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNONNULL();
            //        // pattern_pair IS NULL!
            //        // ..., regexp2, regexp1, pattern_pair
            //        JVMTools_POP();
            //        // ..., regexp2, regexp1
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., regexp1, regexp2
            //        JVMTools_new(PatternPairClass.FullName, typeof(string), typeof(string));
            //        // ..., pattern_pair
            //        JVMTools_DUP();
            //        // ..., pattern_pair, pattern_pair
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, position.Index()));
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        // ..., pattern_pair, pattern_pair, pos-idx
            //        JVMTools_SWAP();
            //        // ..., pattern_pair, pos-idx, pattern_pair
            //        JVMTools_getField(typeof(System.Collections.IDictionary), "pattern_pairs");
            //        // ..., pattern_pair, pos-idx, pattern_pair, pattern_pairs
            //        JVMTools_DUP_X2();
            //        JVMTools_POP();
            //        // ..., pattern_pair, pattern_pairs, pos-idx, pattern_pair
            //        JVMTools_invokeInterface(typeof(object), typeof(System.Collections.IDictionary), 
            //            "put", typeof(object), typeof(object));
            //        JVMTools_POP();
            //        // ..., pattern_pair
            //        org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //        // pattern_pair is NOT null!
            //        // ..., regexp2, regexp1, pattern_pair
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_DUP_X2();
            //        bh.SetTarget(ih);
            //        JVMTools_POP();
            //        JVMTools_POP();
            //        JVMTools_POP();
            //        // ..., pattern_pair
            //        org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_NOP();
            //        bh2.SetTarget(ih2);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._MATCHES_:
            //    {
            //        // ..., arg2, arg1
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        JVMTools_SWAP();
            //        // ..., (String) arg1, arg2
            //        JVMTools_DUP();
            //        JVMTools_instanceOf(typeof(java.util.regex.Pattern));
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFEQ();
            //        // Pattern
            //        // ..., (String) arg1, arg2
            //        JVMTools_cast(typeof(java.util.regex.Pattern));
            //        org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //        // goto "push ONE or ZERO object" code
            //        // NOT Pattern
            //        // ..., (String) arg1, arg2
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_toAwkString();
            //        bh.SetTarget(ih);
            //        JVMTools_invokeStatic(typeof(java.util.regex.Pattern), typeof(java.util.regex.Pattern
            //            ), "compile", typeof(string));
            //        org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_SWAP();
            //        bh2.SetTarget(ih2);
            //        // ..., (Pattern) arg2, (String) arg1
            //        JVMTools_invokeVirtual(typeof(java.util.regex.Matcher), typeof(java.util.regex.Pattern
            //            ), "matcher", typeof(java.lang.ICharSequence));
            //        JVMTools_invokeVirtual(typeof(bool), typeof(java.util.regex.Matcher), "find");
            //        org.apache.bcel.generic.BranchHandle bh3 = JVMTools_IFEQ();
            //        il.Append(factory.CreateFieldAccess(classname, "ONE", GetObjectType(typeof(int)), 
            //            org.apache.bcel.Constants.GETSTATIC));
            //        org.apache.bcel.generic.BranchHandle bh4 = JVMTools_GOTO();
            //        org.apache.bcel.generic.InstructionHandle ih3 = il.Append(factory.CreateFieldAccess
            //            (classname, "ZERO", GetObjectType(typeof(int)), org.apache.bcel.Constants.GETSTATIC
            //            ));
            //        bh3.SetTarget(ih3);
            //        org.apache.bcel.generic.InstructionHandle ih4 = JVMTools_NOP();
            //        bh4.SetTarget(ih4);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._TO_NUMBER_:
            //    {
            //        // call to toBoolean
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(bool), JRT_Class, "toBoolean", typeof(object));
            //        org.apache.bcel.generic.BranchHandle bh3 = JVMTools_IFEQ();
            //        il.Append(factory.CreateFieldAccess(classname, "ONE", GetObjectType(typeof(int)), 
            //            org.apache.bcel.Constants.GETSTATIC));
            //        org.apache.bcel.generic.BranchHandle bh4 = JVMTools_GOTO();
            //        org.apache.bcel.generic.InstructionHandle ih3 = il.Append(factory.CreateFieldAccess
            //            (classname, "ZERO", GetObjectType(typeof(int)), org.apache.bcel.Constants.GETSTATIC
            //            ));
            //        bh3.SetTarget(ih3);
            //        org.apache.bcel.generic.InstructionHandle ih4 = JVMTools_NOP();
            //        bh4.SetTarget(ih4);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SPLIT_:
            //    {
            //        int numargs = position.IntArg(0);
            //        JVMTools_getVariable(convfmt_offset, true, false);
            //        // true = is_global, false = NOT an array
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        if (numargs == 2)
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "split", typeof(object), typeof(object
            //                ), typeof(string));
            //        }
            //        else
            //        {
            //            if (numargs == 3)
            //            {
            //                JVMTools_invokeStatic(typeof(int), JRT_Class, "split", typeof(object), typeof(object
            //                    ), typeof(object), typeof(string));
            //            }
            //            else
            //            {
            //                throw new System.Exception(numargs + ": Too many arguments for split.");
            //            }
            //        }
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SQRT_:
            //    {
            //        JVMTools_toDouble(1);
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "sqrt", typeof(double)
            //            );
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._LOG_:
            //    {
            //        JVMTools_toDouble(1);
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "log", typeof(double));
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SIN_:
            //    {
            //        JVMTools_toDouble(1);
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "sin", typeof(double));
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._COS_:
            //    {
            //        JVMTools_toDouble(1);
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "cos", typeof(double));
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._EXP_:
            //    {
            //        JVMTools_toDouble(1);
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "exp", typeof(double));
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._ATAN2_:
            //    {
            //        // ..., arg2, arg1
            //        JVMTools_toDouble(2);
            //        // ..., arg1, arg2	[as doubles]
            //        JVMTools_invokeStatic(typeof(double), typeof(System.Math), "atan2", typeof(double
            //            ), typeof(double));
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._INDEX_:
            //    {
            //        // ..., arg2, arg1
            //        JVMTools_toAwkString();
            //        JVMTools_SWAP();
            //        JVMTools_toAwkString();
            //        // ..., arg1, arg2
            //        JVMTools_invokeVirtual(typeof(int), typeof(string), "indexOf", typeof(string));
            //        // ..., int
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, 1));
            //        JVMTools_IADD();
            //        // ..., int+1
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SUBSTR_:
            //    {
            //        int numargs = position.IntArg(0);
            //        // ..., [endpos], startpos, string_obj
            //        JVMTools_toAwkString();
            //        // ..., [endpos], startpos, string
            //        if (numargs == 2)
            //        {
            //            JVMTools_invokeStatic(typeof(string), JRT_Class, "substr", typeof(object), typeof(
            //                string));
            //        }
            //        else
            //        {
            //            JVMTools_invokeStatic(typeof(string), JRT_Class, "substr", typeof(object), typeof(
            //                object), typeof(string));
            //        }
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CONSUME_INPUT_:
            //    {
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, false));
            //        JVMTools_invokeVirtual(typeof(bool), JRT_Class, "jrtConsumeInput", typeof(bool));
            //        JVMTools_IFEQ(position.AddressArg());
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._GETLINE_INPUT_:
            //    {
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, true));
            //        JVMTools_invokeVirtual(typeof(bool), JRT_Class, "jrtConsumeInput", typeof(bool));
            //        JVMTools_DUP();
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        JVMTools_SWAP();
            //        // ..., Integer(retcode), retcode for getline
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFLE();
            //        // 1
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        il.Append(factory.CreateFieldAccess(JRT_Class.FullName, "input_line", GetObjectType
            //            (typeof(string)), org.apache.bcel.Constants.GETFIELD));
            //        org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //        // 0 or -1
            //        org.apache.bcel.generic.InstructionHandle ih = il.Append(new org.apache.bcel.generic.PUSH
            //            (cp, string.Empty));
            //        bh.SetTarget(ih);
            //        org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_NOP();
            //        bh2.SetTarget(ih2);
            //        // ..., retcode for getline, input-string
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._GET_INPUT_FIELD_:
            //    {
            //        GetInputField();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._USE_AS_FILE_INPUT_:
            //    case org.jawk.intermediate.AwkTuples._USE_AS_COMMAND_INPUT_:
            //    {
            //        // ..., filename-as-object-type
            //        JVMTools_toAwkString();
            //        // ..., filename
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        // ..., filename, JRT
            //        JVMTools_DUP_X1();
            //        // ..., JRT, filename, JRT
            //        JVMTools_SWAP();
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._USE_AS_FILE_INPUT_:
            //            {
            //                // ..., JRT, JRT, filename
            //                JVMTools_invokeVirtual(typeof(int), JRT_Class, "jrtConsumeFileInputForGetline", typeof(
            //                    string));
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._USE_AS_COMMAND_INPUT_:
            //            {
            //                JVMTools_invokeVirtual(typeof(int), JRT_Class, "jrtConsumeCommandInputForGetline"
            //                    , typeof(string));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for _USE_AS_*_INPUT_: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        // ..., JRT, retcode
            //        JVMTools_SWAP();
            //        // ..., retcode, JRT
            //        JVMTools_invokeVirtual(typeof(string), JRT_Class, "jrtGetInputString");
            //        // ..., retcode, input-string
            //        // NOTE: 2 items on the stack !!!
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._CLOSE_:
            //    {
            //        JVMTools_toAwkString();
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(int), JRT_Class, "jrtClose", typeof(string));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SYSTEM_:
            //    {
            //        JVMTools_toAwkString();
            //        JVMTools_invokeStatic(typeof(int), JRT_Class, "jrtSystem", typeof(string));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._ASSIGN_AS_INPUT_:
            //    {
            //        il.Append(factory.CreateInvoke("java.lang.Object", "toString", GetObjectType(typeof(
            //            string)), BuildArgs(new System.Type[] {  }), INVOKEVIRTUAL));
            //        JVMTools_DUP();
            //        // ..., text, text
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        // ..., text, text, JRT
            //        JVMTools_DUP_X1();
            //        // ..., text, JRT, text, JRT
            //        JVMTools_SWAP();
            //        // ..., text, JRT, JRT, text
            //        il.Append(factory.CreateFieldAccess(JRT_Class.FullName, "input_line", GetObjectType
            //            (typeof(string)), org.apache.bcel.Constants.PUTFIELD));
            //        // ..., text, JRT
            //        JVMTools_invokeVirtual(typeof(void), JRT_Class, "jrtParseFields");
            //        // ..., text (as string, see toString() prior to DUP)
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._ASSIGN_AS_INPUT_FIELD_:
            //    {
            //        AssignAsInputField();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._MATCH_:
            //    {
            //        // ..., ere, s
            //        JVMTools_toAwkString();
            //        JVMTools_SWAP();
            //        JVMTools_toAwkString();
            //        // ..., s, ere
            //        JVMTools_invokeStatic(typeof(java.util.regex.Pattern), typeof(java.util.regex.Pattern
            //            ), "compile", typeof(string));
            //        // ..., s, pattern
            //        JVMTools_SWAP();
            //        // ..., pattern, s
            //        JVMTools_invokeVirtual(typeof(java.util.regex.Matcher), typeof(java.util.regex.Pattern
            //            ), "matcher", typeof(java.lang.ICharSequence));
            //        // ..., matcher
            //        JVMTools_DUP();
            //        // ..., matcher, matcher
            //        JVMTools_invokeVirtual(typeof(bool), typeof(java.util.regex.Matcher), "find");
            //        // ..., matcher, boolean-result
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFEQ();
            //        // A MATCH!
            //        // ..., matcher
            //        JVMTools_DUP();
            //        // ..., matcher, matcher
            //        JVMTools_invokeVirtual(typeof(int), typeof(java.util.regex.Matcher), "end");
            //        JVMTools_SWAP();
            //        JVMTools_invokeVirtual(typeof(int), typeof(java.util.regex.Matcher), "start");
            //        JVMTools_DUP_X1();
            //        // ..., start, end, start
            //        JVMTools_ISUB();
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        JVMTools_storeField(typeof(object), rlength_field);
            //        // ..., start
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, 1));
            //        JVMTools_IADD();
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        JVMTools_DUP();
            //        JVMTools_storeField(typeof(object), rstart_field);
            //        // ..., start()+1
            //        org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //        // !!! NOT A MATCH !!!
            //        // ..., matcher
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_POP();
            //        bh.SetTarget(ih);
            //        il.Append(factory.CreateFieldAccess(classname, "MINUS_ONE", GetObjectType(typeof(
            //            int)), org.apache.bcel.Constants.GETSTATIC));
            //        JVMTools_storeField(typeof(object), rlength_field);
            //        il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //            , org.apache.bcel.Constants.GETSTATIC));
            //        JVMTools_DUP();
            //        JVMTools_storeField(typeof(object), rstart_field);
            //        org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_NOP();
            //        bh2.SetTarget(ih2);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._TOUPPER_:
            //    {
            //        // ..., obj
            //        JVMTools_toAwkString();
            //        // ..., str
            //        il.Append(factory.CreateInvoke(typeof(string).FullName, "toUpperCase", GetObjectType
            //            (typeof(string)), BuildArgs(new System.Type[] {  }), INVOKEVIRTUAL));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._TOLOWER_:
            //    {
            //        // ..., obj
            //        JVMTools_toAwkString();
            //        // ..., str
            //        il.Append(factory.CreateInvoke(typeof(string).FullName, "toLowerCase", GetObjectType
            //            (typeof(string)), BuildArgs(new System.Type[] {  }), INVOKEVIRTUAL));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SUB_FOR_VARIABLE_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        bool is_gsub = position.BoolArg(2);
            //        // ..., orig_value, repl, ere
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_getField(typeof(object), convfmt_field);
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., orig_value, repl, ere, sb, convfmt
            //        if (is_gsub)
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "replaceAll", typeof(object), typeof(
            //                object), typeof(object), typeof(System.Text.StringBuilder), typeof(string));
            //        }
            //        else
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "replaceFirst", typeof(object), typeof(
            //                object), typeof(object), typeof(System.Text.StringBuilder), typeof(string));
            //        }
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., repl_count, new_string
            //        JVMTools_setVariable(offset, is_global);
            //        // ..., repl_count
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SUB_FOR_DOLLAR_0_:
            //    {
            //        // ..., repl, ere
            //        // (target: ..., $field, repl, ere, fieldnum)
            //        // get $0
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_invokeVirtual(typeof(string), JRT_Class, "jrtGetInputString");
            //        JVMTools_DUP_X2();
            //        JVMTools_POP();
            //        // ..., $0, repl, ere
            //        il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //            , org.apache.bcel.Constants.GETSTATIC));
            //    }

            //    case org.jawk.intermediate.AwkTuples._SUB_FOR_DOLLAR_REFERENCE_:
            //    {
            //        // ..., $0, repl, ere, 0
            //        // NO BREAK
            //        bool is_gsub = position.BoolArg(0);
            //        // (start)
            //        // ..., $field, repl, ere, fieldnum
            //        JVMTools_DUP_X2();
            //        // ..., $field, fieldnum, repl, ere, fieldnum
            //        GetInputField();
            //        // ..., $field, fieldnum, repl, ere, orig_value
            //        JVMTools_DUP_X2();
            //        // ..., $field, fieldnum, orig_value, repl, ere, orig_value
            //        JVMTools_POP();
            //        // ..., $field, fieldnum, orig_value, repl, ere
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_getField(typeof(object), convfmt_field);
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., $field, fieldnum, orig_value, repl, ere, sb, convfmt
            //        if (is_gsub)
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "replaceAll", typeof(object), typeof(
            //                object), typeof(object), typeof(System.Text.StringBuilder), typeof(string));
            //        }
            //        else
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "replaceFirst", typeof(object), typeof(
            //                object), typeof(object), typeof(System.Text.StringBuilder), typeof(string));
            //        }
            //        // ..., $field, fieldnum, repl_count
            //        JVMTools_SWAP();
            //        // ..., $field, repl_count, fieldnum
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., $field, repl_count, fieldnum, new_string
            //        JVMTools_SWAP();
            //        // ..., $field, repl_count, new_string, fieldnum
            //        // same as _ASSIGN_AS_INPUT_FIELD_
            //        AssignAsInputField();
            //        JVMTools_POP();
            //        // ..., $field, repl_count
            //        JVMTools_SWAP();
            //        JVMTools_POP();
            //        // ..., repl_count
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SUB_FOR_ARRAY_REFERENCE_:
            //    {
            //        org.apache.bcel.generic.MethodGen lmg = mg;
            //        int arr_offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        bool is_gsub = position.BoolArg(2);
            //        // ..., orig-value, repl-string, ere, array-index
            //        // (target: orig-value, repl-string, ere, sb, convfmt)
            //        org.apache.bcel.generic.LocalVariableGen array_idx_arg = lmg.AddLocalVariable("arr_idx_arg_"
            //             + (++arr_idx_arg_idx), GetObjectType(typeof(object)), null, null);
            //        org.apache.bcel.generic.InstructionHandle ih = il.Append(factory.CreateStore(GetObjectType
            //            (typeof(object)), array_idx_arg.GetIndex()));
            //        array_idx_arg.SetStart(ih);
            //        // ..., orig-value, repl-string, ere
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_getField(typeof(object), convfmt_field);
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., orig-value, repl-string, ere, sb, convfmt
            //        if (is_gsub)
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "replaceAll", typeof(object), typeof(
            //                object), typeof(object), typeof(System.Text.StringBuilder), typeof(string));
            //        }
            //        else
            //        {
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "replaceFirst", typeof(object), typeof(
            //                object), typeof(object), typeof(System.Text.StringBuilder), typeof(string));
            //        }
            //        // ..., repl_count
            //        // (target: repl_count, array, array-idx, value)
            //        JVMTools_getVariable(arr_offset, is_global, true);
            //        // true = is an array
            //        JVMTools_cast(AssocArrayClass);
            //        // ..., repl_count, array
            //        il.Append(factory.CreateLoad(GetObjectType(typeof(object)), array_idx_arg.GetIndex
            //            ()));
            //        // ..., repl_count, array, array-index
            //        JVMTools_getLocalVariable(typeof(System.Text.StringBuilder), "sb");
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., repl_count, array, array-index, value
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "put", typeof(object), typeof(
            //            object));
            //        JVMTools_POP();
            //        // ..., repl_count
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DELETE_ARRAY_ELEMENT_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        JVMTools_getVariable(offset, is_global, true);
            //        // true = is an array
            //        JVMTools_cast(AssocArrayClass);
            //        // array_idx, array
            //        JVMTools_SWAP();
            //        // array, array_idx
            //        JVMTools_invokeVirtual(typeof(object), AssocArrayClass, "remove", typeof(object));
            //        JVMTools_POP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DELETE_ARRAY_:
            //    {
            //        int offset = position.IntArg(0);
            //        bool is_global = position.BoolArg(1);
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ACONST_NULL);
            //        JVMTools_setVariable(offset, is_global);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._IS_IN_:
            //    {
            //        // ..., AssocArray, key
            //        JVMTools_SWAP();
            //        JVMTools_cast(AssocArrayClass);
            //        JVMTools_SWAP();
            //        // ..., AssocArray, key
            //        JVMTools_invokeVirtual(typeof(bool), AssocArrayClass, "isIn", typeof(object));
            //        org.apache.bcel.generic.BranchHandle bh3 = JVMTools_IFEQ();
            //        il.Append(factory.CreateFieldAccess(classname, "ONE", GetObjectType(typeof(int)), 
            //            org.apache.bcel.Constants.GETSTATIC));
            //        org.apache.bcel.generic.BranchHandle bh4 = JVMTools_GOTO();
            //        org.apache.bcel.generic.InstructionHandle ih3 = il.Append(factory.CreateFieldAccess
            //            (classname, "ZERO", GetObjectType(typeof(int)), org.apache.bcel.Constants.GETSTATIC
            //            ));
            //        bh3.SetTarget(ih3);
            //        org.apache.bcel.generic.InstructionHandle ih4 = JVMTools_NOP();
            //        bh4.SetTarget(ih4);
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._INC_DOLLAR_REF_:
            //    case org.jawk.intermediate.AwkTuples._DEC_DOLLAR_REF_:
            //    {
            //        // ..., fieldnum
            //        // JVMTools_toDouble();
            //        // JVMTools_D2I();
            //        JVMTools_DUP();
            //        // ..., fieldnum, fieldnum
            //        GetInputField();
            //        // ..., fieldnum, value
            //        JVMTools_toDouble(1);
            //        // ADD ONE
            //        il.Append(new org.apache.bcel.generic.PUSH(cp, 1.0));
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._INC_DOLLAR_REF_:
            //            {
            //                JVMTools_DADD();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._DEC_DOLLAR_REF_:
            //            {
            //                JVMTools_DSUB();
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for inc/dec dollar ref: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        // ..., fieldnum, value+1
            //        JVMTools_fromDoubleToNumber();
            //        JVMTools_SWAP();
            //        // ..., value+1, fieldnum
            //        // same as _ASSIGN_AS_INPUT_FIELD_
            //        AssignAsInputField();
            //        JVMTools_POP();
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._PLUS_EQ_INPUT_FIELD_:
            //    case org.jawk.intermediate.AwkTuples._MINUS_EQ_INPUT_FIELD_:
            //    case org.jawk.intermediate.AwkTuples._MULT_EQ_INPUT_FIELD_:
            //    case org.jawk.intermediate.AwkTuples._DIV_EQ_INPUT_FIELD_:
            //    case org.jawk.intermediate.AwkTuples._MOD_EQ_INPUT_FIELD_:
            //    case org.jawk.intermediate.AwkTuples._POW_EQ_INPUT_FIELD_:
            //    {
            //        // ..., incval, fieldnum
            //        JVMTools_DUP_X1();
            //        // ..., fieldnum, incval, fieldnum
            //        GetInputField();
            //        // ..., fieldnum, incval, value
            //        JVMTools_toDouble(2);
            //        switch (opcode)
            //        {
            //            case org.jawk.intermediate.AwkTuples._PLUS_EQ_INPUT_FIELD_:
            //            {
            //                // ..., fieldnum, value, incval (as doubles)
            //                JVMTools_DADD();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MINUS_EQ_INPUT_FIELD_:
            //            {
            //                JVMTools_DSUB();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MULT_EQ_INPUT_FIELD_:
            //            {
            //                JVMTools_DMUL();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._DIV_EQ_INPUT_FIELD_:
            //            {
            //                JVMTools_DDIV();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._MOD_EQ_INPUT_FIELD_:
            //            {
            //                JVMTools_DREM();
            //                break;
            //            }

            //            case org.jawk.intermediate.AwkTuples._POW_EQ_INPUT_FIELD_:
            //            {
            //                JVMTools_invokeStatic(typeof(double), typeof(System.Math), "pow", typeof(double), 
            //                    typeof(double));
            //                break;
            //            }

            //            default:
            //            {
            //                throw new System.Exception("Invalid opcode for inc/dec_eq dollar ref: " + org.jawk.intermediate.AwkTuples
            //                    .ToOpcodeString(opcode));
            //            }
            //        }
            //        // ..., fieldnum, sum
            //        JVMTools_fromDoubleToNumber();
            //        // used to be:
            //        //
            //        // JVMTools_SWAP();
            //        // // ..., sum, fieldnum
            //        // assignAsInputField();
            //        // // ..., sum (as string result from assignInputField())
            //        //
            //        // But, problem is that the evaluated expression always returns
            //        // as a string with this method (assignInputField() leaves
            //        // a String on the stack).
            //        // To avoid this problem,
            //        // we'll leave the actual sum on the stack, removing the
            //        // return value from assignAsInputField().
            //        // ..., fieldnum, sum (as double)
            //        JVMTools_DUP_X1();
            //        // ..., sum, fieldnum, sum
            //        JVMTools_SWAP();
            //        // ..., sum, sum, fieldnum
            //        AssignAsInputField();
            //        // ..., sum, sum (as string)
            //        JVMTools_POP();
            //        // ..., sum (as double)
            //        // leave result on the stack
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SRAND_:
            //    {
            //        int numargs = position.IntArg(0);
            //        if (numargs == 0)
            //        {
            //            JVMTools_getField(typeof(int), "oldseed");
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //            JVMTools_invokeStatic(typeof(int), JRT_Class, "timeSeed");
            //            JVMTools_DUP();
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //            JVMTools_SWAP();
            //        }
            //        else
            //        {
            //            // ..., oldseed, this, seed, this, seed
            //            JVMTools_toDouble();
            //            JVMTools_D2I();
            //            JVMTools_getField(typeof(int), "oldseed");
            //            JVMTools_SWAP();
            //            // ..., oldseed, seed
            //            JVMTools_DUP();
            //            il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //            JVMTools_DUP_X2();
            //            JVMTools_SWAP();
            //        }
            //        // ..., oldseed, this, seed, this, seed
            //        // ..., oldseed, this, seed, this, seed
            //        il.Append(factory.CreateFieldAccess(classname, "oldseed", GetObjectType(typeof(int
            //            )), org.apache.bcel.Constants.PUTFIELD));
            //        // ..., oldseed, this, seed
            //        JVMTools_invokeStatic(typeof(java.util.Random), JRT_Class, "newRandom", typeof(int
            //            ));
            //        // ..., oldseed, this, random_#_generator
            //        il.Append(factory.CreateFieldAccess(classname, "random_number_generator", GetObjectType
            //            (typeof(java.util.Random)), org.apache.bcel.Constants.PUTFIELD));
            //        // ..., oldseed
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._RAND_:
            //    {
            //        JVMTools_getField(typeof(java.util.Random), "random_number_generator");
            //        // ..., random_#_generator
            //        org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNONNULL();
            //        // random_#_generator is NULL
            //        JVMTools_invokeStatic(typeof(int), JRT_Class, "timeSeed");
            //        // ..., seed
            //        JVMTools_DUP();
            //        // ..., seed, seed
            //        JVMTools_invokeStatic(typeof(java.util.Random), JRT_Class, "newRandom", typeof(int
            //            ));
            //        // ..., seed, random_#_generator
            //        il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //        // ..., seed, random_#_generator, this
            //        JVMTools_DUP_X2();
            //        JVMTools_SWAP();
            //        // ..., this, seed, this, random_#_generator
            //        il.Append(factory.CreateFieldAccess(classname, "random_number_generator", GetObjectType
            //            (typeof(java.util.Random)), org.apache.bcel.Constants.PUTFIELD));
            //        // ..., this, seed
            //        il.Append(factory.CreateFieldAccess(classname, "oldseed", GetObjectType(typeof(int
            //            )), org.apache.bcel.Constants.PUTFIELD));
            //        // ...
            //        org.apache.bcel.generic.InstructionHandle ih = JVMTools_getField(typeof(java.util.Random
            //            ), "random_number_generator");
            //        bh.SetTarget(ih);
            //        // ..., random_#_generator
            //        JVMTools_invokeVirtual(typeof(double), typeof(java.util.Random), "nextDouble");
            //        JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //        // ..., random_# (as a Double class)
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._APPLY_RS_:
            //    {
            //        JVMTools_getField(JRT_Class, "input_runtime");
            //        JVMTools_getVariable(rs_offset, true, false);
            //        // true = is global, false = is NOT an array
            //        JVMTools_invokeVirtual(typeof(void), JRT_Class, "applyRS", typeof(object));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._LENGTH_:
            //    {
            //        int numargs = position.IntArg(0);
            //        if (numargs == 0)
            //        {
            //            il.Append(factory.CreateFieldAccess(classname, "ZERO", GetObjectType(typeof(int))
            //                , org.apache.bcel.Constants.GETSTATIC));
            //            GetInputField();
            //        }
            //        // ..., obj
            //        JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //        // ..., string
            //        JVMTools_invokeVirtual(typeof(int), typeof(string), "length");
            //        // ..., length
            //        JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //        // ..., length (as Integer)
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._SLEEP_:
            //    {
            //        int numargs = position.IntArg(0);
            //        if (numargs == 0)
            //        {
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, 1000L));
            //        }
            //        else
            //        {
            //            JVMTools_toDouble();
            //            JVMTools_D2L();
            //            il.Append(new org.apache.bcel.generic.PUSH(cp, 1000L));
            //            JVMTools_LMUL();
            //        }
            //        JVMTools_invokeStatic(typeof(void), typeof(java.lang.Thread), "sleep", typeof(long
            //            ));
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._DUMP_:
            //    {
            //        int numargs = position.IntArg(0);
            //        if (numargs == 0)
            //        {
            //            // no args
            //            // dump all variables
            //            System.Collections.Generic.IDictionary<string, int> global_var_offset_map = tuples
            //                .GetGlobalVariableOffsetMap();
            //            foreach (string name in global_var_offset_map.Keys)
            //            {
            //                // dump "name = value" onto stdout
            //                // ...
            //                JVMTools_print(name + " = ");
            //                JVMTools_getStaticField(typeof(Sharpen.Runtime).FullName, "out", typeof(System.IO.TextWriter
            //                    ));
            //                int offset = global_var_offset_map[name];
            //                JVMTools_getField(typeof(object), "global_" + offset);
            //                // if it's a map, get its "map" field
            //                // for printing
            //                JVMTools_DUP();
            //                JVMTools_instanceOf(AssocArrayClass);
            //                org.apache.bcel.generic.BranchHandle bh = JVMTools_IFEQ();
            //                // it is an AssocArray!
            //                JVMTools_cast(AssocArrayClass);
            //                il.Append(factory.CreateFieldAccess(AssocArrayClass.FullName, "map", GetObjectType
            //                    (typeof(System.Collections.IDictionary)), org.apache.bcel.Constants.GETFIELD));
            //                org.apache.bcel.generic.InstructionHandle ih = JVMTools_invokeVirtual(typeof(void
            //                    ), typeof(System.IO.TextWriter), "println", typeof(object));
            //                bh.SetTarget(ih);
            //            }
            //        }
            //        else
            //        {
            //            // ..., argN, argN-1, ..., arg2, arg1
            //            for (int i = 0; i < numargs; ++i)
            //            {
            //                // ..., arg
            //                JVMTools_cast(AssocArrayClass);
            //                il.Append(factory.CreateFieldAccess(AssocArrayClass.FullName, "map", GetObjectType
            //                    (typeof(System.Collections.IDictionary)), org.apache.bcel.Constants.GETFIELD));
            //                JVMTools_getStaticField(typeof(Sharpen.Runtime).FullName, "out", typeof(System.IO.TextWriter
            //                    ));
            //                JVMTools_SWAP();
            //                JVMTools_invokeVirtual(typeof(void), typeof(System.IO.TextWriter), "println", typeof(
            //                    object));
            //            }
            //        }
            //        break;
            //    }

            //    case org.jawk.intermediate.AwkTuples._NF_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._NR_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._FNR_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._FS_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._RS_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._OFS_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._RSTART_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._RLENGTH_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._FILENAME_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._SUBSEP_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._CONVFMT_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._OFMT_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._ENVIRON_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._ARGC_OFFSET_:
            //    case org.jawk.intermediate.AwkTuples._ARGV_OFFSET_:
            //    {
            //        // DO NOTHING!  Done already.
            //        break;
            //    }

            //    default:
            //    {
            //        throw new System.Exception("Unknown opcode: " + org.jawk.intermediate.AwkTuples.ToOpcodeString
            //            (opcode));
            //    }
            //}
        }

        private void ResolveBranchHandleTargets()
        {
            foreach (org.jawk.intermediate.IAddress addr in branch_handles.Keys)
            {
                System.Collections.Generic.IList<org.apache.bcel.generic.BranchHandle> list = branch_handles
                    [addr];
                foreach (org.apache.bcel.generic.BranchHandle bh in list)
                {
                    //bh.SetTarget(instruction_handles[addr.Index()]);
                }
            }
        }

        private void GetInputField()
        {
            // same code as _GET_INPUT_FIELD_
            JVMTools_getField(JRT_Class, "input_runtime");
            JVMTools_SWAP();
            JVMTools_invokeVirtual(typeof (object), JRT_Class, "jrtGetInputField", typeof (object
                                                                                       ));
        }

        private void AssignAsInputField()
        {
            //// ..., text, fieldnum
            //JVMTools_toDouble();
            //JVMTools_D2I();
            //// ..., text, fieldnum (as integer)
            //JVMTools_DUP();
            //// ..., text, fieldnum, fieldnum
            //org.apache.bcel.generic.BranchHandle bh = JVMTools_IFEQ();
            //// $1, $2, ...
            //// ..., text, fieldnum
            //JVMTools_getField(JRT_Class, "input_runtime");
            //JVMTools_DUP_X2();
            //JVMTools_POP();
            //// ..., JRT, text, fieldnum
            //JVMTools_invokeVirtual(typeof(string), JRT_Class, "jrtSetInputField", typeof(object
            //    ), typeof(int));
            //org.apache.bcel.generic.BranchHandle bh2 = JVMTools_GOTO();
            //// $0
            //// ..., text, fieldnum
            //org.apache.bcel.generic.InstructionHandle ih = JVMTools_POP();
            //bh.SetTarget(ih);
            //// ..., text
            //JVMTools_invokeVirtual(typeof(string), typeof(object), "toString");
            //JVMTools_DUP();
            //// ..., text, text
            //JVMTools_getField(JRT_Class, "input_runtime");
            //// ..., text, text, JRT
            //JVMTools_DUP_X1();
            //// ..., text, JRT, text, JRT
            //JVMTools_SWAP();
            //// ..., text, JRT, JRT, text
            //il.Append(factory.CreateFieldAccess(JRT_Class.FullName, "input_line", GetObjectType
            //    (typeof(string)), org.apache.bcel.Constants.PUTFIELD));
            //// ..., text, JRT
            //JVMTools_invokeVirtual(typeof(void), JRT_Class, "jrtParseFields");
            //// ..., text
            //org.apache.bcel.generic.InstructionHandle ih2 = JVMTools_NOP();
            //bh2.SetTarget(ih2);
        }

        ////////////////////////////////////////////////////////////////////////////////
        private void JVMTools_allocateStaticField(System.Type vartype, string varname)
        {
            //JVMTools_allocateStaticField(vartype, varname, ACC_PRIVATE);
        }

        private void JVMTools_allocateStaticField(System.Type vartype, string varname, int
                                                                                           public_or_private)
        {
            //org.apache.bcel.generic.FieldGen fg = new org.apache.bcel.generic.FieldGen(public_or_private
            //     | ACC_STATIC | ACC_FINAL, GetObjectType(vartype), varname, cp);
            //cg.AddField(fg.GetField());
        }

        private void JVMTools_allocateField(System.Type vartype, string varname)
        {
            //org.apache.bcel.generic.FieldGen fg = new org.apache.bcel.generic.FieldGen(ACC_PRIVATE
            //    , GetObjectType(vartype), varname, cp);
            //cg.AddField(fg.GetField());
        }

        private void JVMTools_GOTO(org.jawk.intermediate.IAddress addr)
        {
            //org.apache.bcel.generic.BranchHandle bh = il.Append(new org.apache.bcel.generic.GOTO
            //    (null));
            //JVMTools_addBranchHandle(addr, bh);
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_GOTO()
        {
            //return il.Append(new org.apache.bcel.generic.GOTO(null));
            return null;
        }

        private void JVMTools_IFEQ(org.jawk.intermediate.IAddress addr)
        {
            //org.apache.bcel.generic.BranchHandle bh = il.Append(new org.apache.bcel.generic.IFEQ
            //    (null));
            //JVMTools_addBranchHandle(addr, bh);
        }

        private void JVMTools_IFNE(org.jawk.intermediate.IAddress addr)
        {
            //org.apache.bcel.generic.BranchHandle bh = il.Append(new org.apache.bcel.generic.IFNE
            //    (null));
            //JVMTools_addBranchHandle(addr, bh);
        }

        private void JVMTools_IFLE(org.jawk.intermediate.IAddress addr)
        {
            //org.apache.bcel.generic.BranchHandle bh = il.Append(new org.apache.bcel.generic.IFLE
            //    (null));
            //JVMTools_addBranchHandle(addr, bh);
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_IFNONNULL()
        {
            //return il.Append(new org.apache.bcel.generic.IFNONNULL(null));
            return null;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_NOP()
        {
            //return il.Append(org.apache.bcel.generic.IInstructionConstants.NOP);
            return null;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_SWAP()
        {
            //return il.Append(org.apache.bcel.generic.IInstructionConstants.SWAP);
            return null;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_POP()
        {
            //return il.Append(org.apache.bcel.generic.IInstructionConstants.POP);
            return null;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_POP2()
        {
            //return il.Append(org.apache.bcel.generic.IInstructionConstants.POP2);
            return null;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_DUP()
        {
            //return il.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            return null;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_DUP_X1()
        {
            return null; //return il.Append(org.apache.bcel.generic.IInstructionConstants.DUP_X1);
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_DUP_X2()
        {
            return null; //return il.Append(org.apache.bcel.generic.IInstructionConstants.DUP_X2);
        }

        private void JVMTools_DUP2()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP2);
        }

        private void JVMTools_DUP2_X1()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP2_X1);
        }

        private void JVMTools_DUP2_X2()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP2_X2);
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_D2I()
        {
            return null; //return il.Append(org.apache.bcel.generic.IInstructionConstants.D2I);
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_I2D()
        {
            return null; //return il.Append(org.apache.bcel.generic.IInstructionConstants.I2D);
        }

        private void JVMTools_D2L()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.D2L);
        }

        private void JVMTools_IADD()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.IADD);
        }

        private void JVMTools_ISUB()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ISUB);
        }

        private void JVMTools_DADD()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DADD);
        }

        private void JVMTools_DSUB()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DSUB);
        }

        private void JVMTools_DMUL()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DMUL);
        }

        private void JVMTools_DDIV()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DDIV);
        }

        private void JVMTools_DREM()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DREM);
        }

        private void JVMTools_DNEG()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DNEG);
        }

        private void JVMTools_LMUL()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.LMUL);
        }

        private void JVMTools_returnVoid()
        {
            //il.Append(factory.CreateReturn(org.apache.bcel.generic.Type.VOID));
        }

        private void JVMTools_pushInteger(int i)
        {
            //il.Append(new org.apache.bcel.generic.PUSH(cp, i));
            //JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
        }

        private void JVMTools_pushDouble(double d)
        {
            //il.Append(new org.apache.bcel.generic.PUSH(cp, d));
            //JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
        }

        private void JVMTools_pushString(string s)
        {
            //il.Append(new org.apache.bcel.generic.PUSH(cp, s));
        }

        private void JVMTools_pushBoolean(bool b)
        {
            //il.Append(new org.apache.bcel.generic.PUSH(cp, b));
        }

        private void JVMTools_invokeInterface(System.Type return_type, System.Type orig_class
                                              , string method_name)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] {  }), INVOKEINTERFACE));
        }

        private void JVMTools_invokeInterface(System.Type return_type, System.Type orig_class
                                              , string method_name, System.Type arg_type)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type }), INVOKEINTERFACE));
        }

        private void JVMTools_invokeInterface(System.Type return_type, System.Type orig_class
                                              , string method_name, System.Type arg_type, System.Type arg2_type)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type, arg2_type }), INVOKEINTERFACE));
        }

        private void JVMTools_invokeStatic(System.Type return_type, System.Type orig_class
                                           , string method_name)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] {  }), INVOKESTATIC));
        }

        private void JVMTools_invokeStatic(System.Type return_type, System.Type orig_class
                                           , string method_name, System.Type arg_type)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type }), INVOKESTATIC));
        }

        private void JVMTools_invokeStatic(System.Type return_type, System.Type orig_class
                                           , string method_name, System.Type arg_type, System.Type arg2_type)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type, arg2_type }), INVOKESTATIC));
        }

        private void JVMTools_invokeStatic(System.Type return_type, System.Type orig_class
                                           , string method_name, System.Type arg_type, System.Type arg2_type,
                                           System.Type arg3_type
            )
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type, arg2_type, arg3_type }), INVOKESTATIC
            //    ));
        }

        private void JVMTools_invokeStatic(System.Type return_type, System.Type orig_class
                                           , string method_name, System.Type arg_type, System.Type arg2_type,
                                           System.Type arg3_type
                                           , System.Type arg4_type)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type, arg2_type, arg3_type, arg4_type }), INVOKESTATIC
            //    ));
        }

        private void JVMTools_invokeStatic(System.Type return_type, System.Type orig_class
                                           , string method_name, System.Type arg_type, System.Type arg2_type,
                                           System.Type arg3_type
                                           , System.Type arg4_type, System.Type arg5_type)
        {
            //il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType(return_type
            //    ), BuildArgs(new System.Type[] { arg_type, arg2_type, arg3_type, arg4_type, arg5_type
            //     }), INVOKESTATIC));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_invokeVirtual(System.Type
                                                                                     return_type, System.Type orig_class,
                                                                                 string method_name)
        {
            return null; //return il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType
            //    (return_type), BuildArgs(new System.Type[] {  }), INVOKEVIRTUAL));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_invokeVirtual(System.Type
                                                                                     return_type, System.Type orig_class,
                                                                                 string method_name,
                                                                                 System.Type arg_type)
        {
            return null; //return il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType
            //    (return_type), BuildArgs(new System.Type[] { arg_type }), INVOKEVIRTUAL));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_invokeVirtual(System.Type
                                                                                     return_type, System.Type orig_class,
                                                                                 string method_name,
                                                                                 System.Type arg_type,
                                                                                 System.Type arg_type2)
        {
            return null; //return il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType
            //    (return_type), BuildArgs(new System.Type[] { arg_type, arg_type2 }), INVOKEVIRTUAL
            //    ));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_invokeVirtual(System.Type
                                                                                     return_type, System.Type orig_class,
                                                                                 string method_name,
                                                                                 System.Type arg_type,
                                                                                 System.Type arg_type2,
                                                                                 System.Type arg_type3)
        {
            return null; //return il.Append(factory.CreateInvoke(orig_class.FullName, method_name, GetObjectType
            //    (return_type), BuildArgs(new System.Type[] { arg_type, arg_type2, arg_type3 }), 
            //    INVOKEVIRTUAL));
        }

        private void JVMTools_allocateLocalVariable(System.Type vartype, string varname)
        {
            ////assert local_vars.get(varname) == null;
            //org.apache.bcel.generic.LocalVariableGen lg = mg.AddLocalVariable(varname, GetObjectType
            //    (vartype), null, null);
            //local_vars[varname] = lg.GetIndex();
            //lg.SetStart(JVMTools_NOP());
        }

        private void JVMTools_allocateFunctionParameters(string[] param_names)
        {
            for (int i = 0; i < param_names.Length; i++)
            {
                //assert local_vars.get(param_names[i]) == null;
                local_vars[param_names[i]] = i + 1;
            }
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_getLocalVariable(System.Type
                                                                                        vartype, string varname)
        {
            int I = local_vars[varname];
            if (I == null)
            {
                throw new System.Exception(varname + " not found as a local variable");
            }
            return null; //return il.Append(factory.CreateLoad(GetObjectType(vartype), I));
        }

        private void JVMTools_storeToLocalVariable(System.Type vartype, string varname)
        {
            //int I = local_vars[varname];
            //if (I == null)
            //{
            //    throw new System.Exception(varname + " not found as a local variable");
            //}
            //il.Append(factory.CreateStore(GetObjectType(vartype), I));
        }

        private void JVMTools_addBranchHandle(org.jawk.intermediate.IAddress addr, org.apache.bcel.generic.BranchHandle
                                                                                       bh)
        {
            System.Collections.Generic.IList<org.apache.bcel.generic.BranchHandle> list = branch_handles
                [addr];
            if (list == null)
            {
                branch_handles[addr] = list = new System.Collections.Generic.List<org.apache.bcel.generic.BranchHandle
                                                  >();
            }
            list.Add(bh);
        }

        private void JVMTools_print(string const_str)
        {
            //JVMTools_getStaticField("java.lang.System", "out", typeof(System.IO.TextWriter));
            //il.Append(new org.apache.bcel.generic.PUSH(cp, const_str));
            //JVMTools_invokeVirtual(typeof(void), typeof(System.IO.TextWriter), "print", typeof(
            //    string));
        }

        private void JVMTools_println()
        {
            JVMTools_getStaticField("java.lang.System", "out", typeof (System.IO.TextWriter));
            JVMTools_invokeVirtual(typeof (void), typeof (System.IO.TextWriter), "println");
        }

        private void JVMTools_printlnWithPS()
        {
            // ..., ps
            JVMTools_DUP();
            JVMTools_invokeVirtual(typeof (void), typeof (System.IO.TextWriter), "println");
        }

        // ..., ps
        private org.apache.bcel.generic.InstructionHandle JVMTools_getStaticField(string classname, string fieldname,
                                                                                  System.Type fieldtype)
        {
            return null; //return il.Append(factory.CreateFieldAccess(classname, fieldname, GetObjectType(fieldtype
            //    ), org.apache.bcel.Constants.GETSTATIC));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_getField(System.Type fieldtype, string fieldname)
        {
            //org.apache.bcel.generic.InstructionHandle ih = il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //il.Append(factory.CreateFieldAccess(classname, fieldname, GetObjectType(fieldtype), org.apache.bcel.Constants.GETFIELD));
            //return ih;
            return null;
        }

        private void JVMTools_storeStaticField(System.Type fieldtype, string fieldname)
        {
            //il.Append(factory.CreateFieldAccess(classname, fieldname, GetObjectType(fieldtype
            //    ), org.apache.bcel.Constants.PUTSTATIC));
        }

        private void JVMTools_storeField(System.Type fieldtype, string fieldname)
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ALOAD_0);
            //JVMTools_SWAP();
            //il.Append(factory.CreateFieldAccess(classname, fieldname, GetObjectType(fieldtype
            //    ), org.apache.bcel.Constants.PUTFIELD));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_printString()
        {
            org.apache.bcel.generic.InstructionHandle ih = JVMTools_getStaticField("java.lang.System"
                                                                                   , "out",
                                                                                   typeof (System.IO.TextWriter));
            JVMTools_SWAP();
            JVMTools_invokeVirtual(typeof (void), typeof (System.IO.TextWriter), "print", typeof (
                                                                                              string));
            return ih;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_printStringWithPS()
        {
            // ..., string, ps
            org.apache.bcel.generic.InstructionHandle ih = JVMTools_DUP_X1();
            JVMTools_SWAP();
            JVMTools_invokeVirtual(typeof (void), typeof (System.IO.TextWriter), "print", typeof (
                                                                                              string));
            // ..., ps
            return ih;
        }

        private void JVMTools_new(string newtype)
        {
            //il.Append(factory.CreateNew(newtype));
            //JVMTools_DUP();
            //il.Append(factory.CreateInvoke(newtype, "<init>", org.apache.bcel.generic.Type.VOID
            //    , BuildArgs(new System.Type[] {  }), INVOKESPECIAL));
        }

        private void JVMTools_new(string newtype, System.Type paramtype)
        {
            JVMTools_new(il, newtype, paramtype);
        }

        private void JVMTools_new(org.apache.bcel.generic.InstructionList il, string newtype
                                  , System.Type paramtype)
        {
            //il.Append(factory.CreateNew(newtype));
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP_X1);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.SWAP);
            //il.Append(factory.CreateInvoke(newtype, "<init>", org.apache.bcel.generic.Type.VOID
            //    , BuildArgs(new System.Type[] { paramtype }), INVOKESPECIAL));
        }

        private void JVMTools_new(string newtype, System.Type paramtype1, System.Type paramtype2
            )
        {
            //// ..., param1, param2
            //il.Append(factory.CreateNew(newtype));
            //// ..., param1, param2, objref
            //JVMTools_DUP_X2();
            //JVMTools_DUP_X2();
            //JVMTools_POP();
            //// ..., objref, objref, param1, param2
            //il.Append(factory.CreateInvoke(newtype, "<init>", org.apache.bcel.generic.Type.VOID
            //    , BuildArgs(new System.Type[] { paramtype1, paramtype2 }), INVOKESPECIAL));
        }

        private void JVMTools_instanceOf(System.Type checkclass)
        {
            //il.Append(factory.CreateInstanceOf(new org.apache.bcel.generic.ObjectType(checkclass
            //    .FullName)));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_cast(System.Type to)
        {
            return null; //return il.Append(factory.CreateCheckCast(new org.apache.bcel.generic.ObjectType(to
            //    .FullName)));
        }

        private void JVMTools_swap2()
        {
            JVMTools_DUP2_X2();
            JVMTools_POP2();
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_toAwkString()
        {
            org.apache.bcel.generic.InstructionHandle ih = JVMTools_getVariable(convfmt_offset
                                                                                , true, false);
            // true = is_global, false = NOT an array
            JVMTools_invokeVirtual(typeof (string), typeof (object), "toString");
            JVMTools_invokeStatic(typeof (string), JRT_Class, "toAwkString", typeof (object), typeof (
                                                                                                  string));
            return ih;
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_toAwkStringForOutput()
        {
            org.apache.bcel.generic.InstructionHandle ih = JVMTools_getVariable(ofmt_offset,
                                                                                true, false);
            // true = is_global, false = NOT an array
            JVMTools_invokeVirtual(typeof (string), typeof (object), "toString");
            JVMTools_invokeStatic(typeof (string), JRT_Class, "toAwkStringForOutput", typeof (object
                                                                                          ), typeof (string));
            return ih;
        }

        private void JVMTools_toDouble()
        {
            JVMTools_invokeStatic(typeof (double), JRT_Class, "toDouble", typeof (object));
        }

        private void JVMTools_toDouble(int num_refs)
        {
            if (num_refs == 1)
            {
                JVMTools_toDouble();
            }
            else
            {
                if (num_refs == 2)
                {
                    JVMTools_toDouble();
                    JVMTools_storeRegister();
                    JVMTools_toDouble();
                    JVMTools_loadRegister();
                    JVMTools_swap2();
                }
                else
                {
                    throw new System.Exception("num_refs of " + num_refs + " unsupported.");
                }
            }
        }

        private void JVMTools_storeRegister()
        {
            JVMTools_storeToLocalVariable(typeof (double), "dregister");
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_loadRegister()
        {
            return JVMTools_getLocalVariable(typeof (double), "dregister");
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_ifInt()
        {
            // stack: ..., double
            JVMTools_DUP2();
            // ..., double, double
            JVMTools_D2I();
            // ..., double, int
            JVMTools_I2D();
            // ..., double, double
            JVMTools_DCMPL();
            // ..., result
            return JVMTools_IFEQ();
        }

        private void JVMTools_DCMPL()
        {
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DCMPL);
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_IFEQ()
        {
            return null; //return il.Append(new org.apache.bcel.generic.IFEQ(null));
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_IFNE()
        {
            return null; //return il.Append(new org.apache.bcel.generic.IFNE(null));
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_IFLE()
        {
            return null; //return il.Append(new org.apache.bcel.generic.IFLE(null));
        }

        private void JVMTools_fromDoubleToNumber()
        {
            //JVMTools_DUP2();
            //org.apache.bcel.generic.BranchHandle bh = JVMTools_ifInt();
            //// double here
            //JVMTools_invokeStatic(typeof(double), typeof(double), "valueOf", typeof(double));
            //org.apache.bcel.generic.BranchHandle bh_end = JVMTools_GOTO();
            //org.apache.bcel.generic.InstructionHandle ih = JVMTools_D2I();
            //// int here
            //bh.SetTarget(ih);
            //JVMTools_invokeStatic(typeof(int), typeof(int), "valueOf", typeof(int));
            //org.apache.bcel.generic.InstructionHandle ih_end = JVMTools_NOP();
            //bh_end.SetTarget(ih_end);
        }

        private org.apache.bcel.generic.BranchHandle JVMTools_ifStringNotEquals(string str
            )
        {
            // stack: ..., stringref
            JVMTools_pushString(str);
            JVMTools_invokeVirtual(typeof (bool), typeof (string), "equals", typeof (object));
            return JVMTools_IFEQ();
        }

        private void JVMTools_newAssocArray()
        {
            //il.Append(factory.CreateNew(AssocArrayClass.FullName));
            //il.Append(org.apache.bcel.generic.IInstructionConstants.DUP);
            //il.Append(new org.apache.bcel.generic.PUSH(cp, parameters.sorted_array_keys));
            //// false = not in sorted order
            //il.Append(factory.CreateInvoke(AssocArrayClass.FullName, "<init>", org.apache.bcel.generic.Type
            //    .VOID, BuildArgs(new System.Type[] { typeof(bool) }), INVOKESPECIAL));
        }

        private org.apache.bcel.generic.InstructionHandle JVMTools_getVariable(int offset
                                                                               , bool is_global, bool is_array)
        {
            if (offset < 0)
            {
                throw new System.ArgumentException("offset = " + offset + " ?!  is_global=" + is_global
                                                   + ", is_array=" + is_array);
            }
            org.apache.bcel.generic.InstructionHandle retval;
            if (is_global)
            {
                retval = JVMTools_getField(typeof (object), "global_" + offset);
                JVMTools_DUP();
                org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNONNULL();
                JVMTools_POP();
                if (is_array)
                {
                    JVMTools_newAssocArray();
                }
                else
                {
                    JVMTools_pushString(string.Empty);
                }
                JVMTools_DUP();
                JVMTools_storeField(typeof (object), "global_" + offset);
                org.apache.bcel.generic.InstructionHandle ih = JVMTools_NOP();
                //bh.SetTarget(ih);
            }
            else
            {
                retval = JVMTools_getLocalVariable(typeof (object), "locals_" + offset);
                JVMTools_DUP();
                org.apache.bcel.generic.BranchHandle bh = JVMTools_IFNONNULL();
                JVMTools_POP();
                if (is_array)
                {
                    JVMTools_newAssocArray();
                }
                else
                {
                    JVMTools_pushString(string.Empty);
                }
                JVMTools_DUP();
                JVMTools_storeToLocalVariable(typeof (object), "locals_" + offset);
                org.apache.bcel.generic.InstructionHandle ih = JVMTools_NOP();
                //bh.SetTarget(ih);
            }
            return retval;
        }

        private void JVMTools_setVariable(int offset, bool is_global)
        {
            if (is_global)
            {
                JVMTools_storeField(typeof (object), "global_" + offset);
            }
            else
            {
                JVMTools_storeToLocalVariable(typeof (object), "locals_" + offset);
            }
        }

        private void JVMTools_throwNewException(System.Type cls, string msg)
        {
            JVMTools_throwNewException(il, cls, msg);
        }

        private void JVMTools_throwNewException(org.apache.bcel.generic.InstructionList il
                                                , System.Type cls, string msg)
        {
            //il.Append(new org.apache.bcel.generic.PUSH(cp, msg));
            //JVMTools_new(il, cls.FullName, typeof(string));
            ////JVMTools_DEBUG("Throwing end exception: "+msg);
            //il.Append(org.apache.bcel.generic.IInstructionConstants.ATHROW);
        }

        private void JVMTools_DEBUG(string msg)
        {
            //JVMTools_getStaticField(typeof(Sharpen.Runtime).FullName, "out", typeof(System.IO.TextWriter
            //    ));
            //il.Append(new org.apache.bcel.generic.PUSH(cp, "DEBUG: " + msg));
            //JVMTools_invokeVirtual(typeof(void), typeof(System.IO.TextWriter), "println", typeof(
            //    string));
        }

        private void JVMTools_DEBUG(int offset, bool is_global)
        {
            //JVMTools_DEBUG("Variable offset: " + offset + ", " + is_global + " ...");
            //JVMTools_getStaticField(typeof(Sharpen.Runtime).FullName, "out", typeof(System.IO.TextWriter
            //    ));
            //JVMTools_getVariable(offset, is_global, false);
            //// false = is NOT an array
            //JVMTools_invokeVirtual(typeof(void), typeof(System.IO.TextWriter), "println", typeof(
            //    object));
        }

        /// <summary>Print the top-of-stack as an object reference via PrintStream.println().
        /// 	</summary>
        /// <remarks>
        /// Print the top-of-stack as an object reference via PrintStream.println().
        /// <p>
        /// <strong>Warning:</strong> If the top-of-stack is not an
        /// object reference (i.e., an integer or a double), a VerifyError
        /// will occur.
        /// </remarks>
        private void JVMTools_DEBUG_TOS()
        {
            //// ... objref
            //JVMTools_DUP();
            //JVMTools_invokeVirtual(typeof(System.Type), typeof(object), "getClass");
            //JVMTools_getStaticField(typeof(Sharpen.Runtime).FullName, "out", typeof(System.IO.TextWriter
            //    ));
            //JVMTools_SWAP();
            //// ... objref, System.out, objref
            //JVMTools_invokeVirtual(typeof(void), typeof(System.IO.TextWriter), "println", typeof(
            //    object));
        }

        // ... objref
        ////////////////////////////////////////////////////////////////////////////////
        private static org.apache.bcel.generic.Type GetObjectType(System.Type cls)
        {
            //if (cls.IsArray)
            //{
            //    return new org.apache.bcel.generic.ArrayType(GetObjectType(cls.GetElementType()),1);
            //}
            //else
            //{
            //    if (cls == typeof(bool))
            //    {
            //        return (org.apache.bcel.generic.Type.BOOLEAN);
            //    }
            //    else
            //    {
            //        if (cls == typeof(byte))
            //        {
            //            return (org.apache.bcel.generic.Type.BYTE);
            //        }
            //        else
            //        {
            //            if (cls == typeof(char))
            //            {
            //                return (org.apache.bcel.generic.Type.CHAR);
            //            }
            //            else
            //            {
            //                if (cls == typeof(double))
            //                {
            //                    return (org.apache.bcel.generic.Type.DOUBLE);
            //                }
            //                else
            //                {
            //                    if (cls == typeof(float))
            //                    {
            //                        return (org.apache.bcel.generic.Type.FLOAT);
            //                    }
            //                    else
            //                    {
            //                        if (cls == typeof(int))
            //                        {
            //                            return (org.apache.bcel.generic.Type.INT);
            //                        }
            //                        else
            //                        {
            //                            if (cls == typeof(long))
            //                            {
            //                                return (org.apache.bcel.generic.Type.LONG);
            //                            }
            //                            else
            //                            {
            //                                if (cls == typeof(short))
            //                                {
            //                                    return (org.apache.bcel.generic.Type.SHORT);
            //                                }
            //                                else
            //                                {
            //                                    if (cls == typeof(string))
            //                                    {
            //                                        return (org.apache.bcel.generic.Type.STRING);
            //                                    }
            //                                    else
            //                                    {
            //                                        if (cls == typeof(System.Text.StringBuilder))
            //                                        {
            //                                            return (org.apache.bcel.generic.Type.STRINGBUFFER);
            //                                        }
            //                                        else
            //                                        {
            //                                            if (cls == typeof(object))
            //                                            {
            //                                                return (org.apache.bcel.generic.Type.OBJECT);
            //                                            }
            //                                            else
            //                                            {
            //                                                if (cls == typeof(void))
            //                                                {
            //                                                    return (org.apache.bcel.generic.Type.VOID);
            //                                                }
            //                                                else
            //                                                {
            //                                                    return (new org.apache.bcel.generic.ObjectType(cls.FullName));
            //                                                }
            //                                            }
            //                                        }
            //                                    }
            //                                }
            //                            }
            //                        }
            //                    }
            //                }
            //            }
            //        }
            //    }
            //}
            return null; //
        }

        private static org.apache.bcel.generic.Type[] BuildArgs(System.Type[] arguments)
        {
            System.Collections.Generic.List<org.apache.bcel.generic.Type> arg_list = new System.Collections.Generic.List
                <org.apache.bcel.generic.Type>();
            foreach (System.Type cls in arguments)
            {
                arg_list.Add(GetObjectType(cls));
            }
            return arg_list.ToArray();
        }



        #region Instructions Abstraction

        private interface Visitor
        {
            void Visit(StringBuilder output);
        }

        private class AwkScriptSource : Visitor
        {
            public AwkScriptSource()
            {
                Childs = new List<Visitor>();
            }

            public List<Visitor> Childs { get; private set; }

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                output.Append("//AwkScript.il" + Environment.NewLine);

                foreach(Visitor v in Childs)
                {
                    v.Visit(output);
                }
            }

            #endregion
        }

        private class Assembly : Visitor
        {
            public Assembly(string name, bool isExtern) : this(name, isExtern, null) { }

            public Assembly(string name, bool isExtern, Version ver)
            {
                Name = name;
                IsExtern = isExtern;
                Ver = ver;
            }

            public bool IsExtern { get; set; }
            public string Name { get; set; }
            public Version Ver { get; set; }

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                output.Append(".assembly ");
                if(IsExtern) output.Append("extern ");
                output.Append(Name + " {");
                if(Ver!=null) this.Ver.Visit(output);
                output.Append("}" + Environment.NewLine);
            }

            #endregion
        }

        private class Version : Visitor
        {
            public Version(int major, int minor, int build, int revision)
            {
                mMajor = major;
                mMinor = minor;
                mBuild = build;
                mRevision = revision;
            }

            private int mMajor;
            private int mMinor;
            private int mBuild;
            private int mRevision;

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                output.Append(string.Format(".ver {0}:{1}:{2}:{3}", mMajor, mMinor, mBuild, mRevision));
            }

            #endregion
        }

        private class Module : Visitor
        {
            public Module(string name)
            {
                mName = name;
            }

            private string mName;

            #region Visitor Members

            void Visitor.Visit(StringBuilder output)
            {
                output.Append(".module " + mName + Environment.NewLine);
            }

            #endregion
        }

        private class Namespace : Visitor
        {
            public Namespace(string name)
            {
                mName = name;
                Childs = new List<Visitor>();
            }

            private string mName;

            public List<Visitor> Childs { get; private set; }

            #region Visitor Members

            public void Visit(StringBuilder output)
            {

                output.Append(".namespace " + mName + Environment.NewLine);
                output.Append("{" + Environment.NewLine);
                foreach(Visitor v in Childs)
                {
                    v.Visit(output);
                }
                output.Append("}" + Environment.NewLine);
            }

            #endregion
        }

        private class Class : Visitor
        {
            public Class(string name)
            {
                mName = name;
                Childs = new List<Visitor>();
            }

            private string mName;
            public List<Visitor> Childs { get; private set; }

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                output.Append(".class " + mName);
                output.Append("{" + Environment.NewLine);
                foreach(Visitor v in Childs)
                {
                    v.Visit(output);
                }
                output.Append("}" + Environment.NewLine);
            }

            #endregion
        }


        private enum Visibility
        {
            Public,Private,Protected,Internal
        }

        private class Field<T> : Visitor
        {
            public Field(
                string name,
                T initValue)
                : this(name, initValue, false, false, Visibility.Private) { }

            public Field(
                string name,
                T initValue,
                bool isStatic,
                bool isReadonly)
                : this(name, initValue, isStatic, isReadonly, Visibility.Private) { }

            public Field(
                string name,
                T initValue,
                bool isStatic,
                bool isReadonly,
                Visibility visibility)
            {
                mName = name;
                mType = typeof(T);
                mInitValue = initValue;
                mIsStatic = isStatic;
                mIsReadonly = isReadonly;
                mVisibility = visibility;
            }

            private string mName;
            private Type mType;
            private T mInitValue;
            private bool mIsStatic = false;
            private bool mIsReadonly = false;
            private Visibility mVisibility = Visibility.Private;

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                output.Append(".field " + mVisibility.ToString().ToLower());
                if(mIsStatic) output.Append(" static");
                if(mIsReadonly) output.Append(" initonly");
                output.Append(" " + mType.Name + " " + mName + Environment.NewLine);
            }

            #endregion
        }

        private class Method : Visitor
        {
            public Method(string name, Type returnType) : this(name, returnType, null, Visibility.Public, false, false) { }

            public Method(string name, Type returnType, Type[] parameters, Visibility visibility, bool isStatic, bool isMain)
            {
                mName = name;
                mType = returnType;
                mIsStatic = isStatic;
                mVisibility = visibility;
                mIsMain = isMain;
                mParameters = parameters;
                Instructions = new List<Instruction>();
                LocalVariables = new List<LocalVariable>();
            }

            protected string mName;
            private Type mType;
            protected bool mIsStatic;
            protected Visibility mVisibility;
            private bool mIsMain;
            protected Type[] mParameters;

            public List<Instruction> Instructions { get; set; }
            public List<LocalVariable> LocalVariables { get; private set; }

            public int GetLocalVariableIndex(string varName)
            {
                var variable = (from a in LocalVariables where a.VarName == varName select a).FirstOrDefault(null);
            
                if(variable!=null)
                {
                    return LocalVariables.IndexOf(variable);
                }

                throw new NullReferenceException("LocalVariable not found : "+varName);
            }

            public int MaxStack { get; set; }

            #region Visitor Members

            public virtual void Visit(StringBuilder output)
            {
                output.Append(".method " + mVisibility.ToString().ToLower() + " ");
                if (mIsStatic) output.Append("static ");
                output.Append(mType.Name + " ");
                output.Append(mName + " (");
                if (mParameters != null)
                {
                    for (int i = 0; i < mParameters.Length; i++)
                    {
                        if (i > 0) output.Append(", ");
                        output.Append(mParameters[i].Name);
                    }
                }
                output.Append(" ) cil managed" + Environment.NewLine);
                output.Append("{" + Environment.NewLine);
                output.Append(".maxstack " + this.MaxStack);

                if (mIsMain) output.Append(".entrypoint ");

                foreach (Instruction instruction in Instructions)
                {
                    instruction.Visit(output);
                }
                output.Append("}" + Environment.NewLine);
            }

            #endregion
        }

        private class Constructor : Method
        {
            public Constructor()
                : this(null, Visibility.Public, false)
            {

            }

            public Constructor(Type[] parameters, Visibility visibility, bool isStatic)
                : base(".ctor", null, parameters, visibility, isStatic, false)
            {
                
            }

            public override void Visit(StringBuilder output)
            {
                output.Append(".method " + mVisibility.ToString().ToLower() + " specialname rtspecialname ");
                if (mIsStatic) output.Append("static ");
                output.Append(" instance void .ctor(");

                if (mParameters != null)
                {
                    for (int i = 0; i < mParameters.Length; i++)
                    {
                        if (i > 0) output.Append(", ");
                        output.Append(mParameters[i].Name);
                    }
                }
                output.Append(") cil managed" + Environment.NewLine);
                output.Append("{" + Environment.NewLine);
                output.Append(".maxstack " + this.MaxStack);

                foreach (Instruction instruction in Instructions)
                {
                    instruction.Visit(output);
                }
                output.Append("}" + Environment.NewLine);
            }
        }

        private class Properties : Visitor
        {

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                throw new NotImplementedException();
            }

            #endregion
        }

        private class Instruction : Visitor
        {

            #region Visitor Members

            public virtual void Visit(StringBuilder output)
            {
                throw new NotImplementedException();
            }

            #endregion
        }

        private class BranchedInstruction : Instruction
        {
            public override void Visit(StringBuilder output)
            {
                base.Visit(output);
            }
        }

        private interface LocalVariable : Visitor
        {
            string VarName
            {
                get;
            }
        }

        private class TypedLocalVariable<T> : LocalVariable
        {
            public TypedLocalVariable(string varName, T initValue)
            {
                VarName = varName;
            }

            public string VarName { get; set; }

            #region Visitor Members

            public void Visit(StringBuilder output)
            {
                throw new NotImplementedException();
            }

            #endregion


        }

        #endregion



    }






}
